xcode 我可以在运行时禁用特定子视图的自动布局吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11368440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 04:28:14  来源:igfitidea点击:

Can I disable autolayout for a specific subview at runtime?

xcodexcode4interface-builderxcode4.3autolayout

提问by terriblememory

I have a view that needs to have its frame manipulated programmatically - it's a kind of document view that wraps to its content which is then scrolled and zoomed around a superview by manipulating the frame origin. Autolayout fights with this at runtime.

我有一个需要以编程方式操作其框架的视图 - 它是一种文档视图,可以包装其内容,然后通过操纵框架原点在超级视图周围滚动和缩放。自动布局在运行时与此作斗争。

Disabling autolayout completely seems a bit harsh because it could reasonably be used to handle layout for the other views. It seems like what I might want is some kind of "null constraint".

完全禁用自动布局似乎有点苛刻,因为它可以合理地用于处理其他视图的布局。看起来我可能想要的是某种“空约束”。

回答by Muhammad Aamir Ali

I had the same problem. But I have resolved it.
Yes, you can disable auto layout at runtime for a specific UIView, instead of disabling it for the whole xib or storyboard which is set by default in Xcode 4.3 and later.

我有同样的问题。但是我已经解决了。
是的,您可以在运行时禁用特定的自动布局UIView,而不是在 Xcode 4.3 及更高版本中默认设置的整个 xib 或故事板禁用它。

Set translatesAutoresizingMaskIntoConstraintsto YES, before you set the frame of your subview:

设置translatesAutoresizingMaskIntoConstraintsYES, 在设置子视图的框架之前:

self.exampleView.translatesAutoresizingMaskIntoConstraints = YES;
self.exampleView.frame = CGRectMake(20, 20, 50, 50);

回答by jmstone617

I had a similar issue where Autolayout was overriding some of my frame-setting at run time (I had a dynamic view that in some cases pushed a new view controller...pushing and then pressing Back would reset the initial view).

我有一个类似的问题,其中 Autolayout 在运行时覆盖了我的一些框架设置(我有一个动态视图,在某些情况下推送了一个新的视图控制器......推送然后按 Back 将重置初始视图)。

I got around this by putting my manipulation code in viewDidLayoutSubviewsof my View Controller. This seems to get called after whatever constraint mojo gets called, but before viewDidAppear, so the user is none the wiser.

我通过将我的操作代码放在viewDidLayoutSubviews我的视图控制器中来解决这个问题。这似乎是在调用任何约束 mojo 之后调用的,但在 viewDidAppear 之前,因此用户并不聪明。

回答by Jon Hull

Perhaps just setting translatesAutoresizingMaskIntoConstraintsto YES(and not adding additional constraints affecting that view) will let you set the frame without fighting the auto layout system.

也许只是设置translatesAutoresizingMaskIntoConstraintsYES(并且不添加影响该视图的其他约束)可以让您设置框架而不与自动布局系统发生冲突。

回答by bandejapaisa

In iOS 8 you can set an NSLayoutConstraint to be active or not. So if I'm using interface builder, I add all my constraints to an OutletCollection and then activate or deactivate using:

在 iOS 8 中,您可以设置 NSLayoutConstraint 是否处于活动状态。因此,如果我使用界面构建器,我会将所有约束添加到 OutletCollection,然后使用以下方法激活或停用:

NSLayoutConstraint.deactivateConstraints(self.landscapeConstraintsPad)
NSLayoutConstraint.activateConstraints(self.portraitConstraintsPad)

The particular application I'm using it for here is having different constraints in portrait and landscape mode and I activate/deactivate based on the rotation of the device. It means I can create some complex layout changes all in interface builder for both orientations, and still use auto layout without the verbose auto layout code.

我在这里使用它的特定应用程序在纵向和横向模式下有不同的限制,我根据设备的旋转来激活/停用。这意味着我可以在界面构建器中为两个方向创建一些复杂的布局更改,并且仍然使用自动布局而无需冗长的自动布局代码。

Or you can activate / deactivate using removeConstraints and addConstraints.

或者您可以使用 removeConstraints 和 addConstraints 激活/停用。

回答by michaelsnowden

I don't know if this will help anyone else, but I wrote a category to make this convenient because I find myself doing this a lot.

我不知道这对其他人是否有帮助,但我写了一个类别来方便这一点,因为我发现自己经常这样做。

UIView+DisableAutolayoutTemporarily.h

UIView+DisableAutolayoutTemporively.h

#import <UIKit/UIKit.h>

@interface UIView (DisableAutolayoutTemporarily)

// the view as a parameter is a convenience so we don't have to always
// guard against strong-reference cycles
- (void)resizeWithBlock:(void (^)(UIView *view))block;

@end

UIView+DisableAutolayoutTemporarily.m

UIView+DisableAutolayoutTemporously.m

#import "UIView+DisableAutoResizeTemporarily.h"
@implementation UIView (DisableAutoResizeTemporarily)

- (void)resizeWithBlock:(void (^)(UIView * view))block
{
    UIView *superview = self.superview;
    [self removeFromSuperview];
    [self setTranslatesAutoresizingMaskIntoConstraints:YES];
    __weak UIView *weakSelf = self;
    block(weakSelf);
    [superview addSubview:self];
}

@end

I use it like this:

我像这样使用它:

[cell.argumentLabel resizeWithBlock:^(UIView *view) {
    [view setFrame:frame];
}];

Hope it helps.

希望能帮助到你。

回答by renaun

You can set the translatesAutoresizingMaskIntoConstraintstype Boolean, Value Yes in the User Defined Runtime Attributes of the UIView you want in the xib/storyboard.

你可以在 xib/storyboard 中你想要的 UIView 的 User Defined Runtime Attributes 中设置translatesAutoresizingMaskIntoConstraintstype Boolean, Value Yes 。

回答by Mike Bobbitt

  • Open project in 4.5
  • Select storyboard
  • Open the file inspector
  • Under Interface Builder Document uncheck 'Use Autolayout'
  • 在 4.5 中打开项目
  • 选择故事板
  • 打开文件检查器
  • 在 Interface Builder Document 下取消选中“使用自动布局”

You can split across multiple storyboards if you want to use autolayout for some views.

如果您想对某些视图使用自动布局,您可以拆分多个故事板。

回答by Andrespch

For me it worked to create the subview programmatically, in my case the auto layout was messing with a view that I needed to rotate around its center but once I created this view programmatically it worked.

对我来说,它可以以编程方式创建子视图,在我的情况下,自动布局与我需要围绕其中心旋转的视图混淆,但是一旦我以编程方式创建了这个视图,它就可以工作了。

回答by Big D

In my view I had a Label and a Text. The label had pan gesture. The label moves around fine during drag. But when I use the text box keyboard, the label resets its position to the original location defined in auto layout. The issue got resolved when I added the following in swift for the label. I added this in viewWillAppear but it can be added pretty much anywhere you have access to the target field.

在我看来,我有一个标签和一个文本。标签有平移手势。标签在拖动过程中可以很好地移动。但是当我使用文本框键盘时,标签将其位置重置为自动布局中定义的原始位置。当我为标签快速添加以下内容时,问题得到了解决。我在 viewWillAppear 中添加了它,但它几乎可以添加到您可以访问目标字段的任何地方。

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true

回答by Myles Caley

Instead of disabling autolayout, I would just calculate the new constraint with the frame you are replacing. That appears to me to be the appropriate way. If you are adjusting components that rely on constraints, adjust them accordingly.

我不会禁用自动布局,而是使用您要替换的框架计算新约束。这在我看来是合适的方式。如果您要调整依赖约束的组件,请相应地调整它们。

For example, if you have a vertical constraint of 0 between two views (myView and otherView), and you have a pan gesture or something that adjusts the height of myView then you can recalculate the constraint with the adjusted values.

例如,如果您在两个视图(myView 和 otherView)之间的垂直约束为 0,并且您有平移手势或调整 myView 高度的东西,那么您可以使用调整后的值重新计算约束。

self.verticalConstraint.constant = newMyViewYOriginValue - (self.otherView.frame.origin.y + self.otherView.frame.size.height);
[self.myView needsUpdateConstraints];