我可以在同一视图上使用setFrame和自动布局吗?

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

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

是的,这可以做到。

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

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

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

当你这样做的时候, 你仍然需要确保这些自动约束可以满足其余约束条件

所以, setFrame:例子,假设已经有约束条件决定了你的视图的大小和位置,然后你设置了translatesAutoresizingMaskIntoConstraints = YES并且调用了setFrame:setFrame:的调用将在视图上生成新的约束,这可能与已经存在的约束相冲突。

(事实上​​,这个错误经常发生,如果你看到一条日志消息抱怨冲突约束,其中一个约束是一个NSAutoresizingMaskLayoutConstraint ,那么你看到的是与自动约束冲突,这是一个容易犯的错误,因为translatesAutoresizingMaskIntoConstraints = YES是默认值,所以如果你在代码中configuration约束,如果你不想要这些自动约束,你需要记得把它closures。

相比之下,再次假设已经存在的约束决定了你的视图的大小和位置,但是在你调用setFrame:之前,你需要设置translatesAutoresizingMaskIntoConstraints = NO 。 在这种情况下,你的setFrame:调用不会产生新的约束,所以在单独的约束之间不会有冲突。 但是,在这种情况下, 约束与您设置的框架值之间仍然存在“冲突”。 在下一次自动布局被调用的时候,它会在视图上看到已经存在的约束条件,计算它们所需要的帧值,并将帧设置为所需的值本身,并且手动设置你设置的值。

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

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

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

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

设置属性translationAutoresizingMaskIntoConstraints = true这将工作后视图确实出现或button上设置,只是在视图确实出现后。

有些东西对我来说很简单,就是为我的约束添加一个IBOutlet给视图控制器,然后改变sockets上的constant属性。

例如,要更改视图的x原点,请将该视图的主要约束设置为您的控制器。 换句话说,创build一个出口@IBOutlet var labelXOrigin: NSLayoutConstraint! 。 然后,当你想调整x的位置,只需做一些类似的事情

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

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

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]; } 

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