我可以在同一视图上使用setFrame和autolayout吗?

时间:2012-11-01 23:10:00

标签: iphone cocoa-touch interface-builder frame autolayout

我想为所有按钮添加填充,因此我将UIButton子类化,除了其他更改之外,我还想使用setFrame方法添加固定填充。除了setFrame之外,一切正常。我查了一下,我发现如果我在该视图上取消选中“使用AutoLayout”,那么我可以使用setFrame,它可以工作。有没有解决的办法?我真的想使用自动布局,因为它有助于使应用程序在iphone 5和早期设备上都看起来不错。但是我也想在我的子类中使用setFrame,让我的生活更轻松。

总结一下,我的问题是:我可以使用autolayout并以编程方式调整UIView的框架吗?

5 个答案:

答案 0 :(得分:202)

是的,这可以做到。

如果您设置了视图translatesAutoresizingMaskIntoConstraints = YES,那么对setFrame:的调用会在运行时自动转换为基于视图当前autoresizingMask的布局约束。这使您可以将基于帧的布局与基于约束的布局混合使用。

例如,您可以使用自动布局来定义视图的所有子视图的布局,但仍然可以调用setFrame:来设置视图本身的大小和位置。从您的角度来看,您正在使用自动布局和直接帧操作的混合进行布局。但系统实际上是使用约束来处理所有事情。

但是,使用translatesAutoresizingMaskIntoConstraints时有一个很大的警告。

执行此操作时,仍然需要确保其余约束条件能够满足这些自动约束

因此,例如,假设已经存在确定视图大小和位置的约束,然后您设置translatesAutoresizingMaskIntoConstraints = YES并调用setFrame:。对setFrame:的调用将在视图上生成新约束,这可能与已存在的约束冲突。

(实际上,这个错误经常发生。如果你看到一条抱怨冲突约束的日志消息,其中一个约束是NSAutoresizingMaskLayoutConstraint,那么你所看到的是与自动约束的冲突这是一个容易犯的错误,因为translatesAutoresizingMaskIntoConstraints = YES是默认值,所以如果您在代码中配置约束,则需要记住在不需要这些自动约束时将其关闭。)

相反,再次假设已存在确定视图大小和位置的约束,但在调用translatesAutoresizingMaskIntoConstraints = NO之前设置setFrame:。在这种情况下,您的setFrame:调用不会产生新约束,因此单独约束之间不会发生冲突。但是,在这种情况下,约束与您设置的帧值之间仍存在“冲突” 。在下次调用自动布局时,它将在视图上看到已存在的约束,计算它们所需的帧值,并将帧设置为所需的值本身,破坏您手动设置的值。

有关详情,请参阅Apple Cocoa Auto Layout Guide中的“采用自动布局”部分。

答案 1 :(得分:16)

对我来说最简单的事情是删除我想从其超级视图移动/调整大小的视图,设置其frame,然后将其添加回来。例如,在UILabel子类中使用自定义UITableViewCell

[cell.myLabel removeFromSuperview];
cell.myLabel.frame = someFrameIGenerated;
[cell.contentView addSubview:cell.myLabel];

答案 2 :(得分:3)

对我有用的只是为视图控制器添加IBOutlet我的约束,然后更改插座上的constant属性。

例如,要更改视图的x原点,请将该视图的前导约束中的插座设置为控制器。换句话说,创建一个插座@IBOutlet var labelXOrigin: NSLayoutConstraint!。然后,当您想要调整x位置时,只需执行类似

的操作
self.labelXOrigin.constant = 20.0 // Or whatever origin you want to set.

答案 3 :(得分:2)

  

设置子视图框架的最佳方法是viewWillLayoutSubviews方法   自动布局项目。

     

set property translatedAutoresizingMaskIntoConstraints = true this   将在视图确实显示后工作,或者在按钮上设置选项卡,就在之后   视图确实出现了。

答案 4 :(得分:0)

如果您的应用不支持多种设备方向。

viewDidLoad 中设置要调整大小的视图的框架

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [aView setFrame:CGRectMake(15, 15, 100, 100)];
}

然后在 viewDidLayoutSubviews

-(void)viewDidLayoutSubviews
{
    [self.view setTranslatesAutoresizingMaskIntoConstraints:NO];
}

我不确定,但我认为如果您使用此解决方案,将一个方向切换到另一个方向可能会导致问题