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

时间:2012-07-06 19:20:35

标签: xcode xcode4 interface-builder xcode4.3 autolayout

我有一个视图,需要以编程方式操作它的框架 - 它是一种包含其内容的文档视图,然后通过操作框架原点滚动并围绕超视图进行缩放。 Autolayout在运行时与此斗争。

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

14 个答案:

答案 0 :(得分:166)

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

在设置子视图的框架之前,将translatesAutoresizingMaskIntoConstraints设置为YES

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

答案 1 :(得分:49)

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

我通过将操作代码放在View Controller的viewDidLayoutSubviews中来解决这个问题。这似乎是在调用任何约束mojo之后调用的,但是在viewDidAppear之前,所以用户不是更聪明的。

答案 2 :(得分:26)

或许只是将translatesAutoresizingMaskIntoConstraints设置为YES(并且不会添加影响该视图的其他约束),您可以设置框架而不会对自动布局系统产生影响。

答案 3 :(得分:17)

在iOS 8中,您可以将NSLayoutConstraint设置为活动与否。因此,如果我使用界面构建器,我将所有约束添加到OutletCollection,然后使用以下命令激活或停用:

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

我在这里使用它的特定应用在纵向和横向模式中具有不同的约束,并且我基于设备的旋转来激活/停用。这意味着我可以在界面构建器中为两个方向创建一些复杂的布局更改,并且仍然使用自动布局而不需要详细的自动布局代码。

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

答案 4 :(得分:8)

我不知道这是否会对其他人有所帮助,但是我写了一个类别来使这个方便,因为我发现自己做了很多。

的UIView + DisableAutolayoutTemporarily.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

#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

我这样用:

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

希望它有所帮助。

答案 5 :(得分:6)

您可以在xib / storyboard中所需的UIView的用户定义的运行时属性中设置translatesAutoresizingMaskIntoConstraints类型Boolean,值为是。

答案 6 :(得分:1)

  • 在4.5
  • 中打开项目
  • 选择故事板
  • 打开文件检查器
  • 在Interface Builder Document下取消选中&#39;使用Autolayout&#39;

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

答案 7 :(得分:1)

对我而言,它以编程方式创建子视图,在我的情况下,自动布局弄乱了我需要围绕其中心旋转的视图,但是一旦我以编程方式创建了此视图,它就起作用了。

答案 8 :(得分:1)

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

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true

答案 9 :(得分:0)

在没有故事板或xib文件的项目中发生了这种情况。全部100%代码。我在底部有一个广告横幅,希望视图边界停在广告横幅上。视图将在加载后自动调整大小。我尝试了这个页面上的每个分辨率,但没有一个能够工作。

我最终只是创建了一个缩短高度的子视图,并将其放入控制器的主视图中。然后我的所有内容都进入了子视图。这样就可以很容易地解决这个问题,而不会做任何感觉它与谷物相反的事情。

我在想如果你想要的视图不是填充窗口的正常大小那么你应该使用子视图。

答案 10 :(得分:0)

我遇到了类似的情况,我加入了一个以自动布局启动的项目,但我需要对多个视图进行动态调整。这对我有用:

  1. 请勿在界面构建器中布置视图或组件。

  2. 以编程方式添加视图,以alloc / init开头并正确设置其框架。

  3. 完成。

答案 11 :(得分:0)

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

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

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

答案 12 :(得分:0)

对于那些使用自动布局的人,请查看我的解决方案here。您应该制作要调整的约束@IBOutlet,然后更改它们的常量。

答案 13 :(得分:-16)

如果是xib文件:

  1. 选择.xib文件
  2. 选择“文件所有者”
  3. 显示实用程序
  4. 点击:“文件检查器”
  5. 在“Interface Builder Document”下,禁用:“Use Autolayout”