iOS中的自动布局问题
Posted
技术标签:
【中文标题】iOS中的自动布局问题【英文标题】:Autolayout issue in iOS 【发布时间】:2013-08-17 11:15:45 【问题描述】:我在 UIView 类型的容器视图中有一个标签、图像和按钮。容器视图又是 UIView 类型的超级容器视图的子视图。所有布局都是使用 autlayout 视觉格式语言在代码中完成的。我想要实现的是在按下按钮时删除标签并期望超级容器调整其内容的大小。但目前发生的是整个超级容器从屏幕上消失了。有人能告诉我为什么会这样吗?附上我的代码示例。
- (void)viewDidLoad
[super viewDidLoad];
superContainer = [[UIView alloc] initWithFrame:CGRectZero];
superContainer.backgroundColor = [UIColor orangeColor];
[self.view addSubview:superContainer];
Container = [[UIView alloc] initWithFrame:CGRectZero];
Container.backgroundColor = [UIColor redColor];
[superContainer addSubview:Container];
NSDictionary *sViews = NSDictionaryOfVariableBindings(Container);
[superContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10.0-[Container]-10.0-|" options:0 metrics:nil views:sViews]];
[superContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10.0-[Container]-10.0-|" options:0 metrics:nil views:sViews]];
CGSize temp1 = [superContainer systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
superContainer.frame = CGRectMake(superContainer.frame.origin.x, superContainer.frame.origin.y, temp1.width, temp1.height);
closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
//[closeButton setImage: forState:UIControlStateNormal];
[closeButton setBackgroundImage:[UIImage imageNamed:@"closebox.png"] forState:UIControlStateNormal];
[closeButton addTarget:self action:@selector(hide:) forControlEvents:UIControlEventTouchUpInside];
NSLog(@"Close button frame is %@",NSStringFromCGRect(closeButton.frame));
//closeButton.frame = CGRectMake(0, 10, 32, 32);
[Container addSubview:closeButton];
helpLabel = [[UILabel alloc] init];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"This is sample Text. This is sample Text.This is sample Text. This is sample Text.This is sample Text. This is sample Text.This is sample Text. This is sample Text.This is sample Text. This is sample Text. "];
helpLabel.attributedText = attrString;
helpLabel.numberOfLines = 0;
helpLabel.backgroundColor = [UIColor greenColor];
[Container addSubview:helpLabel];
helpImageView = [[UIImageView alloc] init];
helpImageView.image = [UIImage imageNamed:@"testimage.png"];
NSLog(@"frame of imageview is %@",NSStringFromCGRect(helpImageView.frame));
[Container addSubview:helpImageView];
dismissButton = [UIButton buttonWithType:UIButtonTypeCustom];
[dismissButton setTitle:@"Dismiss" forState:UIControlStateNormal];
[[dismissButton titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];
dismissButton.backgroundColor = [UIColor blueColor];
[Container addSubview:dismissButton];
[Container setClipsToBounds:YES];
[self addAutoLayoutProperties];
NSDictionary *views = NSDictionaryOfVariableBindings(helpLabel,helpImageView,dismissButton,closeButton);
NSDictionary *metrics = @@"buttonHeight":@32.0;
// Horizontal layout - for helplabel
[Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5.0-[helpLabel(400)]-5.0-|" options:NSLayoutFormatAlignAllLeft|NSLayoutFormatAlignAllRight metrics:metrics views:views]];
// Horizontal layout - for helpImageView
[Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[helpImageView]|" options:NSLayoutFormatAlignAllLeft|NSLayoutFormatAlignAllRight metrics:metrics views:views]];
// Horizontal layout - for dismissButton
[Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[dismissButton]-|" options:NSLayoutFormatAlignAllCenterX|NSLayoutFormatAlignAllCenterY metrics:metrics views:views]];
// Horizontal layout - for dismissButton
[Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[closeButton]-1.0-|" options:0 metrics:metrics views:views]];
// Vertical layout
[Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-1.0-[closeButton]" options:0 metrics:metrics views:views]];
[Container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-buttonHeight-[helpLabel]-5.0-[helpImageView]-5.0-[dismissButton]-5.0-|" options:0 metrics:metrics views:views]];
CGSize temp = [Container systemLayoutSizeFittingSize:UILayoutFittingExpandedSize];
Container.frame = CGRectMake(Container.frame.origin.x, Container.frame.origin.y, temp.width, temp.height);
superContainer.center = self.view.center;
我添加自动布局属性的方法
-(void)addAutoLayoutProperties
helpLabel.translatesAutoresizingMaskIntoConstraints = NO;
helpImageView.translatesAutoresizingMaskIntoConstraints = NO;
dismissButton.translatesAutoresizingMaskIntoConstraints = NO;
closeButton.translatesAutoresizingMaskIntoConstraints = NO;
superContainer.translatesAutoresizingMaskIntoConstraints = NO;
Container.translatesAutoresizingMaskIntoConstraints = NO;
我删除标签的方法。
- (IBAction)removeASubview:(id)sender
[helpLabel removeFromSuperview];
还有一个问题。当相关视图从其父视图中移除时,约束对象会发生什么。它们在那里存在还是被删除??
【问题讨论】:
【参考方案1】:您可以添加另一个应在没有helpLabel
及其约束时应用的约束,但给这个新的一个较低的优先级,这样当helpLabel
存在时,它的约束将控制视图,但是当helpLabel
被移除时,新的约束就会发挥作用。例如:
[container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-buttonHeight@500-[helpImageView]" options:0 metrics:metrics views:views]];
顺便说一句,如果您想查看删除 helpLabel
后视图发生了什么变化,请使用调试器运行应用程序,点击暂停按钮 () 以暂停应用程序,然后在 @987654327 @调试器提示,键入以下命令:
请注意,有时很难确定哪个窗口是哪个窗口,因此我会经常为各种视图提供唯一的数字 tag
属性以使其更容易。
此外,在同一命令行中,您可以使用以下命令来识别约束中的模糊布局:
po [[UIWindow keyWindow] _autolayoutTrace]【讨论】:
@Rajashekar 与您的问题无关,但不是手动设置superContainer
的center
,我倾向于添加将superContainer
的centerX 和centerY 对齐的约束它的superview
。这将消除您当前约束的模糊性(将由_autolayoutTrace
报告),并且当您从横向转到纵向时,超级容器将保持居中。
感谢@Rob 回答我的问题。 po提示非常有帮助。我的最终目标是在按下按钮时删除包含三个对象(标签、图像、按钮)的容器,并将其替换为另一个包含不同大小的相同三个对象的容器。为了完成它,我正在努力解决这个问题。你能给我任何建议吗?所有视图都必须由自动布局代码创建。
@Rajashekar 这似乎比你原来的问题更容易。您只需删除旧容器(因此也删除它的所有子视图)并添加具有自己的一组约束的新容器。我不确定我是否明白你在绊倒什么。您已经证明您知道如何添加视图和约束,那么问题是什么?以上是关于iOS中的自动布局问题的主要内容,如果未能解决你的问题,请参考以下文章
iOS - 尝试在 layoutSubviews 中的子视图上设置自动布局