Guf*_*ros 321 iphone cocoa-touch interface-builder ios autolayout
我在IB中设计了自定义Cell,将其子类化并将我的插座连接到我的自定义类.我在单元格内容中有三个子视图:UIView(cdView)和两个标签(titleLabel和emailLabel).根据每行可用的数据,有时我想在我的单元格中显示UIView和两个标签,有时只有两个标签.我想要做的是设置约束,如果我将UIView属性设置为隐藏或我将从superview中删除它,两个标签将移动到左侧.我尝试将UIView前导约束设置为10px的Superview(单元格内容)和UILabels将10 px的约束引导到下一个视图(UIView).稍后在我的代码中
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(IndexPath *)indexPath {
...
Record *record = [self.records objectAtIndex:indexPath.row];
if ([record.imageURL is equalToString:@""]) {
cell.cdView.hidden = YES;
}
Run Code Online (Sandbox Code Playgroud)
我隐藏了我的cell.cdView,我希望标签向左移动,但是它们在Cell中保持相同的位置.我试图从superview中删除cell.cdView,但它也没有用.我附上图片来澄清我的意思.

我知道如何以编程方式执行此操作,而我不是在寻找解决方案.我想要的是在IB中设置约束,并且如果删除或隐藏其他视图,我希望我的子视图将动态移动.是否可以在具有自动布局的IB中执行此操作?
.....
Run Code Online (Sandbox Code Playgroud)
Tim*_*Tim 361
这是可能的,但你必须做一些额外的工作.有一些概念性的东西可以先摆脱困境:
在您的情况下,这可能意味着:
您需要做的是明智地过度约束您的标签.单独留下现有约束(10pts空间到另一个视图),但添加另一个约束:使标签的左边缘与超级视图的左边缘相差10pts,具有非必需的优先级(默认的高优先级可能会很好).
然后,当您希望它们向左移动时,完全删除左视图.左视图的强制10pt约束将与其相关的视图一起消失,并且您将只留下一个高优先级约束,标签距其超视图10pts.在下一个布局过程中,这应该使它们向左扩展,直到它们填充超视图的宽度,但是围绕边缘的间距.
一个重要的警告:如果您希望将左侧视图放回到图片中,则不仅需要将其添加回视图层次结构中,而且还必须同时重新建立其所有约束.这意味着只要再次显示该视图,您就需要一种方法将视图及其标签之间的10pt间距约束放回去.
Max*_*eod 202
在运行时添加或删除约束是一项可能影响性能的重量级操作.但是,有一个更简单的选择.
对于要隐藏的视图,请设置宽度约束.使用与该视图的前导水平间隙约束其他视图.
要隐藏,.constant请将宽度约束更新为0.f. 其他视图将自动向左移动以占据位置.
有关详细信息,请参阅我的其他答案:
Sil*_*ril 80
对于仅支持iOS 8+的用户,有一个新的布尔属性处于活动状态.它将有助于动态地仅启用所需的约束
PS约束出口必须坚固,不弱,
例如:
@IBOutlet weak var optionalView: UIView!
@IBOutlet var viewIsVisibleConstraint: NSLayoutConstraint!
@IBOutlet var viewIsHiddenConstraint: NSLayoutConstraint!
func showView() {
optionalView.isHidden = false
viewIsVisibleConstraint.isActive = true
viewIsHiddenConstraint.isActive = false
}
func hideView() {
optionalView.isHidden = true
viewIsVisibleConstraint.isActive = false
viewIsHiddenConstraint.isActive = true
}
Run Code Online (Sandbox Code Playgroud)
另外,要修复故事板中的错误,您需要取消Installed选中其中一个约束的复选框.
UIStackView (iOS 9+)还有
一个选项是封装您的视图UIStackView.一旦隐藏视图UIStackView将自动更新布局
sid*_*ick 59
UIStackView在其hidden任何子视图(iOS 9+)上更改属性时,会自动重新定位其视图.
UIView.animateWithDuration(1.0) { () -> Void in
self.mySubview.hidden = !self.mySubview.hidden
}
Run Code Online (Sandbox Code Playgroud)
在这个WWDC视频中跳转到11:48进行演示:
Rob*_*ins 16
我的项目使用自定义@IBDesignable子类UILabel(以确保颜色,字体,插图等的一致性),我已经实现了类似以下内容:
override func intrinsicContentSize() -> CGSize {
if hidden {
return CGSizeZero
} else {
return super.intrinsicContentSize()
}
}
Run Code Online (Sandbox Code Playgroud)
这允许标签子类参与自动布局,但隐藏时不占用空间.
jte*_*rry 13
对于Google员工:在Max的答案基础上,为了解决许多人注意到的填充问题,我只是增加了标签的高度,并将该高度用作分隔符而不是实际的填充.对于包含视图的任何场景,可以扩展此想法.
这是一个简单的例子:

在这种情况下,我将Author标签的高度映射到适当的IBOutlet:
@property (retain, nonatomic) IBOutlet NSLayoutConstraint* authorLabelHeight;
Run Code Online (Sandbox Code Playgroud)
当我将约束的高度设置为时0.0f,我们保留"填充",因为" 播放"按钮的高度允许它.
小智 8
将uiview和标签之间的约束连接为IBOutlet,并在设置hidden = YES时将优先级成员设置为较小的值
我最终做的是创建2个xib.一个是左视图,一个没有它.我在控制器中注册了两个,然后决定在cellForRowAtIndexPath期间使用哪个.
它们使用相同的UITableViewCell类.缺点是xib之间存在一些重复内容,但这些单元格非常基本.好处是我没有一堆代码来手动管理删除视图,更新约束等.
一般来说,这可能是一个更好的解决方案,因为它们在技术上是不同的布局,因此应该有不同的xib.
[self.table registerNib:[UINib nibWithNibName:@"TrackCell" bundle:nil] forCellReuseIdentifier:@"TrackCell"];
[self.table registerNib:[UINib nibWithNibName:@"TrackCellNoImage" bundle:nil] forCellReuseIdentifier:@"TrackCellNoImage"];
TrackCell *cell = [tableView dequeueReusableCellWithIdentifier:(appDelegate.showImages ? @"TrackCell" : @"TrackCellNoImage") forIndexPath:indexPath];
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我将Author标签的高度映射到适当的IBOutlet:
@property (retain, nonatomic) IBOutlet NSLayoutConstraint* authorLabelHeight;
Run Code Online (Sandbox Code Playgroud)
当我将约束的高度设置为0.0f时,我们保留"填充",因为"播放"按钮的高度允许它.
cell.authorLabelHeight.constant = 0;
Run Code Online (Sandbox Code Playgroud)
对于此特定布局,要使用的约束是正在隐藏的视图上的“主导”约束。不过,下面的理论在各个方面都适用。
1:设置所有约束,使其在所有视图都可见时呈现出您想要的外观。
2:向要隐藏的视图添加第二个“前导”约束。这将暂时打破限制。
3:将原始主导约束的优先级更改为“999” - 这将优先考虑新约束,该约束将为 1000,并且不会再破坏任何约束。
4:将新约束从“leading=leading”更改为“trailing=leading”。这会将您想要隐藏的视图移离其父级的前缘,将其移开。
5:切换新约束的 isActive 值现在将在视图内或视图外切换。在将可见性设置为 true/false 的同时将其设置为 true/false。例如:
@IBOutlet var avatar:UIImage!
@IBOutlet var avatarLeadHid:NSLayoutConstraint!
func hideAvatar() {
self.avatar.isHidden = true
self.avatarLeadHid.isActive = true
}
func showAvatar() {
self.avatar.isHidden = false
self.avatarLeadHid.isActive = false
}
Run Code Online (Sandbox Code Playgroud)
奖励:您可以调整新隐藏器约束的“常量”值,以更改隐藏视图时要使用的填充/边距。该值可以为负值。
额外奖励:只需切换隐藏器约束上的“已安装”复选框,就可以在界面生成器中查看布局的外观,而无需运行任何代码。
进一步的帮助:我制作了一个视频,展示了我比一系列要点做得更好的地方: https: //youtu.be/3tGEwqtQ-iU
| 归档时间: |
|
| 查看次数: |
157495 次 |
| 最近记录: |