Uitableview 自动布局:如何压缩复杂的popover
如果您喜欢尝试源代码(您非常喜欢),请查看我的 我有一个弹出对话框,显示设置列表。这些设置列在多个UITableView中。UITableView不应可滚动,因为整体设置视图已处于滚动状态。此外,popover对话应根据需要垂直占据尽可能多的屏幕,但应水平压缩 因此,我设想了以下结构:Uitableview 自动布局:如何压缩复杂的popover,uitableview,uiscrollview,uipopovercontroller,uicontainerview,container-view,Uitableview,Uiscrollview,Uipopovercontroller,Uicontainerview,Container View,如果您喜欢尝试源代码(您非常喜欢),请查看我的 我有一个弹出对话框,显示设置列表。这些设置列在多个UITableView中。UITableView不应可滚动,因为整体设置视图已处于滚动状态。此外,popover对话应根据需要垂直占据尽可能多的屏幕,但应水平压缩 因此,我设想了以下结构: UIView => MySettingsViewController - UIScrollView - UIView (Content View) - Container View1
UIView => MySettingsViewController
- UIScrollView
- UIView (Content View)
- Container View1
- UITableView (embedded) => MyTableViewController
- Container View2
- UITableView (embedded)
通过Interface Builder组装结构,并使用Autolayout调整尺寸
我有滚动视图、内容视图(我刚开始时只有一个)和容器视图,它们分别指向各自的超级视图(或布局指南)。我以以下方式约束内容视图的大小:
contentView.width == (topmost) UIView.width
contentView.height == 200 // removed at build time
此外,我将表视图的大小设置为其内容大小,因为否则popover看起来是空的:
类MyTableViewController:UITableViewController{
覆盖功能视图显示(动画:Bool){
super.viewdide显示(动画)
//这是制图语法-意图应该是明确的
布局(视图,替换:ConstraintGroup()){[unowned self]视图
view.width==self.tableView.contentSize.width
view.height==self.tableView.contentSize.height
}
view.setNeedsLayout()文件
}
}
“设置”弹出窗口中充满了内容,但其大小不太正确:
为了解决这个问题,我尝试了以下不起作用的方法:
类MySettingsViewController:UIViewController{
重写变量preferredContentSize:CGSize{
得到{
让compressedSize=view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
//这始终是(0,0),因为子视图尚未调整大小
返回压缩大小
}
设置{
super.preferredContentSize=newValue
}
}
}
总而言之:压缩不起作用。所以我自己解决了这个问题,正如您在查看Bitbucket存储库时看到的那样 现在,在
MyTableViewController
和mysettingviewcontroller
中,布局都已固定。前一个现在看起来像这样:
类MyTableViewController:UITableViewController{
var heightConstraint:NSLayoutConstraint?
var TableViewedgeConstraints:[NSLayoutConstraint]?
覆盖功能视图将出现(动画:Bool){
超级。视图将显示(动画)
如果let container=tableView.superview,其中tableviewEdgeConstraints==nil{
布局(tableView,容器,替换:ConstraintGroup()){[unowned self]tableView,中的容器
self.tableView.edgesconstraints=tableView.edges==inset(container.edges,0)
}
}
}
重写func viewdilayoutsubviews(){
super.viewDidLayoutSubviews()
如果让heightConstraint=heightConstraint{
如果Int(heightConstraint.constant)!=Int(tableView.contentSize.height){
heightConstraint.constant=self.tableView.contentSize.height
}
}否则{
布局(视图,替换:ConstraintGroup()){[unowned self]视图
如果(self.tableView.contentSize.height>0){
self.heightConstraint=view.height==self.tableView.contentSize.height
}
}
}
}
}
因此,基本上,我将表的高度约束为其内容的高度,并在内容的高度发生变化时更改约束。桌子一摆好就可以这样做。此外,嵌套表视图的边固定到容器视图的边上。我认为这是强制性的,因为我无法找到如何在Interface Builder中约束不同场景的两个视图
在MySettingsViewController
中,一旦知道滚动视图的大小,滚动视图的大小就会设置为内容视图框架的大小(可通过出口访问)。此外,为了压缩popover,当高度改变时,设置控制器的preferredContentSize会相应地调整(如果忽略此条件,您可能会陷入无休止的布局循环中)。此外,我做了3件事,使MySettingsViewController周围有一个导航控制器:
类MySettingsViewController:UIViewController{
@ibvar-contentView:UIView!
@iBCROLLVIEW:UIScrollView!
重写func viewdilayoutsubviews(){
super.viewDidLayoutSubviews()
scrollView.contentSize=contentView.frame.size
if(preferredContentSize.height!=scrollView.contentSize.height){
let newSize=CGSize(宽度:400,高度:scrollView.contentSize.height)
preferredContentSize=newSize
presentingViewController?.presentedViewController?.preferredContentSize=newSize
scrollView.contentInset=UIEdgeInsetsMake(0,0,0,0)
}
}
}
这就是结果: