以 Autolayout 视觉形式调整子视图的大小
Posted
技术标签:
【中文标题】以 Autolayout 视觉形式调整子视图的大小【英文标题】:Resize subviews in Autolayout visual form 【发布时间】:2013-10-08 07:00:18 【问题描述】:我未能将我的应用从 Autoresize 迁移到 Autolayout 机制。我所需要的只是一个具有动态大小和子视图的视图,它们将连接到与它们的父视图相同大小的左上角。在 IB 中,我将 PieView(我的超级视图)的大小设置为 186x186。并让 IB 生成所有需要的约束(我将在代码中创建新的约束):
PieView.m -updateConstraints()
- (void)updateConstraints
[super updateConstraints];
[self removeConstraintsAffectingViewAndSubviews];
[self setTranslatesAutoresizingMaskIntoConstraints:NO];
CGFloat sizeCoef = 0.7f;
CGFloat percent = [self.category getFillinPercent] / 100.0f;
percent = percent > 1.0f ? 1.0f : percent;
sizeCoef += (1.0f - sizeCoef) * percent;
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:100.f];//kDiameter * sizeCoef];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:100.0f];//kDiameter * sizeCoef];
//_imgEmptyCircle, _imgFullCircle - UIImageViews
NSDictionary *views = NSDictionaryOfVariableBindings(_imgEmptyCircle, _imgFullCircle, self);
NSDictionary *metrics = @@"height":@100.0;
[self addConstraints:@[width, height]];
NSString *visualForm = @"H:|[_imgEmptyCircle(height)][_imgFullCircle(height)]|";
NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:visualForm
options:0
metrics:metrics
views:views];
visualForm = @"V:|[_imgEmptyCircle(height)][_imgFullCircle(height)]|";
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:visualForm
options:0
metrics:metrics
views:views];
[self addConstraints:verticalConstraints];
[self addConstraints:horizontalConstraints];
结果真让我吃惊。蓝色的如我所愿正确显示,但绿色的有奇怪的行为。
当然我有错误:无法同时满足约束。First imageView: NSIBPrototypingLayoutConstraint:0xa2795d0 'IB 在构建时为固定框架视图自动生成' V:[UIImageView:0x8a37150(186)]> NSLayoutConstraint:0xa0305c0 V:[UIImageView:0x8a37150(100)]第二个 imageView:同一个可能是 PieView: ( NSLayoutConstraint:0x8a40750 V:[CEPieView:0x8a36e50(100)], NSLayoutConstraint:0xa030570 V:|-(0)-[UIImageView:0x8a37150](名称:'|':CEPieView:0x8a36e50), NSLayoutConstraint:0xa0305c0 V:[UIImageView:0x8a37150(100)], NSLayoutConstraint:0xa0305f0 V:[UIImageView:0x8a37150]-(0)-[UIImageView:0xa277cf0]> NSLayoutConstraint:0xa030620 V:[UIImageView:0xa277cf0(100)], NSLayoutConstraint:0xa030650 V:[UIImageView:0xa277cf0]-(0)-| (名称:'|':CEPieView:0x8a36e50) )
请给我建议如何解决它。如何借助 AutoLayout 机制创建和旧的自动调整掩码(UIViewAutoresizingFlexibleHeight、UIViewAutoresizingFlexibleWidth)。任何帮助将不胜感激。
【问题讨论】:
你能解释一下哪个是绿色视图,哪个是蓝色视图?您的视图层次结构如何设置? PieView 有 3 个子视图。其中一个,最后一个,现在没有使用,在讨论中是多余的。第一个 imageView 有蓝色背景,第二个(在 IB 的中间)有绿色背景。谢谢回复 【参考方案1】:您设置约束的方式是错误的。基本上,您要求超级视图为 100pts x 100pts,并包含两个子视图,每个子视图均为 100pts x 100pts,并且彼此相邻且位于彼此之上。因此,首先您的超级视图必须是 200pts 宽和/或高,然后您不能有两个彼此相邻且位于顶部的视图。 你真正想做的(我认为)是:
NSString *visualForm = @"H:|[_imgFullCircle]|"; // No need to explicitly set the height
然后添加相应的约束,然后:
visualForm = @"H:|[_imgEmptyCircle(height)]|";
并为此添加另一个约束,并为垂直约束做同样的事情。
基本上你会得到:
//_imgEmptyCircle, _imgFullCircle - UIImageViews
NSDictionary *views = NSDictionaryOfVariableBindings(_imgEmptyCircle, _imgFullCircle, self);
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_imgEmptyCircle]|"
options:0
metrics:nil
views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_imgFullCircle]|"
options:0
metrics:nil
views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_imgEmptyCircle]|"
options:0
metrics:nil
views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_imgFullCircle]|"
options:0
metrics:nil
views:views]];
【讨论】:
谢谢,我知道我的视觉格式出了什么问题。但我想动态调整超级视图的大小。在您的约束不起作用后,从我上面的代码中调用[self addConstraints:@[width, height]];
。因此,在我的情况下,我想将超级视图的大小从 IB 中的 186x186 调整为代码中的 100x100 并自动调整子视图的大小(也是 100x100)。谢谢!
怎么不工作了?它给你什么结果?通常这应该可以工作,因为子视图被限制为与父视图具有相同的大小(您也可以直接在 IB 中确定)
因此,superview 保持与 IB 中相同的大小。我的代码:....[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_imgFullCircle]|" options:0 metrics:nil views:views]]; [self addConstraints:@[width, height]];
截图 s16.postimg.org/rk14u68ut/…
你有什么错误吗?你能显示[自我约束]的输出吗?您是否尝试过查看您的 -updateContraints 方法何时被调用?
当我添加 `[self addConstraints:@[width, height]];` 时出现无法同时满足约束,我尝试在其中设置超级视图的大小。没有这条线就没有错误。这里有一些日志 (s2.postimg.org/4mzl1f72x/…)以上是关于以 Autolayout 视觉形式调整子视图的大小的主要内容,如果未能解决你的问题,请参考以下文章
使用 UIScrollView 和 AutoLayout 以编程方式创建控制器无法正确调整视图大小