我有一个内部带有ScrollView的ViewController(固定到边缘,有4个约束)。一切都很好。
然后我将一个TableViewController作为ChildViewController添加到ScrollView。 TableViewController被硬编码为具有3行。 TableViewController的视图固定到完整的ScrollView。
@IBOutlet weak var SV: UIScrollView!
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let TVC = storyboard.instantiateViewController(withIdentifier: "TVC") as! TVC
addChildViewController(TVC)
SV.addSubview(TVC.view)
TVC.didMove(toParentViewController: self)
TVC.view.translatesAutoresizingMaskIntoConstraints = false
TVC.view.topAnchor.constraint(equalTo: SV.topAnchor).isActive = true
TVC.view.leadingAnchor.constraint(equalTo: SV.leadingAnchor, constant: 100).isActive = true
TVC.view.trailingAnchor.constraint(equalTo: SV.trailingAnchor, constant: -100).isActive = true
TVC.view.bottomAnchor.constraint(equalTo: SV.bottomAnchor).isActive = true
}
如果打开调试器,则会发现ScrollView布局不明确,并且override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
从未被表视图控制器调用(为什么?)。
相反,如果我只是在故事板或任何其他视图中的滚动视图内添加标签,并向其添加4个约束,则将显示TableView并按预期方式调用override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
。
这是怎么回事? ScrollView不应模棱两可,因为TableView应该计算其自身的固有内容大小? tableview有什么问题,如果单独在ScrollView中,它将永远不会填充自身?
我要添加整个示例项目。如果运行它,则预期结果,将显示表视图。如果您转到情节提要并从ScrollView中删除标签,则将根本不会填充TableView。
我不知道如何直接在此处添加sampleproject,因此我将其上传。只需运行它,然后从情节提要中删除唯一的标签,然后重新运行即可,不再有表格视图。 https://wetransfer.com/downloads/e0a75a995992cdc2be9120224515549920181003074547/1083bc9a3cb34fe9b1ab8e513b1520f020181003074547/e68826
PS:忽略其他内容,例如其中的子视图控件。我唯一的问题是,为什么当标签存在于同一ScrollView中时显示表格视图,而在删除标签时却不显示表格视图。
答案 0 :(得分:0)
首先,应用于ScrollView内的视图的约束有点特殊,可以说。它们没有链接到ScrollView的框架,而是链接到ScrollView的“ contentSize”。通常,如果您在另一个视图内部有一个View,并且该内部视图在所有方向上都固定在superView上,则它会拉伸以匹配父级大小(如果父级约束已很好地定义给其他父级),或者如果未相对于另一个父级定义父级约束,则父级将“包装”子级大小。
现在,在这种情况下,ScrollView的行为略有不同,ScrollView的大小将永远不会“包装”孩子。添加子约束只是为了告诉ScrollView什么是滚动区域(contentSize)。
此外,在您的情况下,您可以将UITableView视为“特殊的” ScrollView,它无法为ScrollView提供足够的信息来计算scrollableContent。如果在所有方向上固定tableView,它只会告诉TableView“在所有方向上与父级对齐”,但是滚动视图将不知道“我可以滚动多少”。
因此,由于上述问题,通常在ScrollView内添加一个UIView充当“容器”,然后根据scrollDirection将视图的宽度/高度设置为等于ScrollView或父视图的父级。 scrollView(再次取决于用例)。然后,将要包含在scrollView中的所有内容添加到UIView中。内容也以这种方式固定,即不允许“压缩”强制父视图(又称容器)拉伸以“包装”整个内容,这样,滚动条将知道滚动条的数量区域。
ScrollView不应模棱两可,因为TableView应该计算其自身的固有内容大小?
这是错误的,固有内容大小定义了视图绘制所需的最小大小。现在考虑一下,绘制一个tableView需要多少空间,如果未添加其他特殊实现,则答案为0。tableView的宽度/高度可以为0,没有任何约束可以防止这种情况。 / p>
现在总结一下,您的实现有些错误,要修复它,我建议仔细看一下众多教程之一,这些教程展示了如何使用自动布局实现UIScrollView。 您将看到大多数实现将: