我想为所有按钮添加填充,因此我将UIButton子类化,除了其他更改之外,我还想使用setFrame方法添加固定填充。除了setFrame之外,一切正常。我查了一下,我发现如果我在该视图上取消选中“使用AutoLayout”,那么我可以使用setFrame,它可以工作。有没有解决的办法?我真的想使用自动布局,因为它有助于使应用程序在iphone 5和早期设备上都看起来不错。但是我也想在我的子类中使用setFrame,让我的生活更轻松。
总结一下,我的问题是:我可以使用autolayout并以编程方式调整UIView的框架吗?
答案 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];
}
我不确定,但我认为如果您使用此解决方案,将一个方向切换到另一个方向可能会导致问题