代码实现UIView未显示在UIScrollView中,宽度约束歧义求助
咱们直接说问题根源和解决办法——你碰到的视图不显示+宽度歧义,本质是UIScrollView的特殊布局逻辑搞的鬼:
问题出在哪?
UIScrollView和普通UIView的布局逻辑不一样:它的frame是由父视图约束决定的,但contentSize(可滚动区域的大小)默认是靠子视图的约束自动推导的。你现在手动设置了contentSize.height = 1000,但没处理宽度;再加上navigationView只绑定了scrollView的top/trailing/leading,系统根本不知道navigationView的宽度该取多大(是和scrollView的显示宽度一致?还是自适应内容?),自然就出现宽度歧义,导致视图没法正常渲染。
解决方案(推荐规范写法)
我更建议用AutoLayout自动计算contentSize,避免手动设置的潜在问题:
步骤1:删掉手动设置的contentSize
先移除这行代码:
scrollView.contentSize.height = 1000
步骤2:给navigationView加明确的宽度约束
让navigationView的宽度和主视图(也就是你的view)保持一致,这样系统能明确它的宽度,同时自动推导出scrollView的contentSize:
navigationView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
修改后的完整代码片段
view.addSubview(scrollView) scrollView.backgroundColor = #colorLiteral(red: 0.968627451, green: 0.968627451, blue: 0.968627451, alpha: 1) scrollView.anchor(top: view.topAnchor, trailing: view.trailingAnchor, bottom: view.bottomAnchor, leading: view.leadingAnchor, topPadding: 0, rightPadding: 0, bottomPadding: 0, leftPadding: 0, width: 0, height: 0) scrollView.addSubview(navigationView) navigationView.backgroundColor = .red navigationView.anchor(top: scrollView.topAnchor, trailing: scrollView.trailingAnchor, bottom: nil, leading: scrollView.leadingAnchor, topPadding: 0, rightPadding: 0, bottomPadding: 0, leftPadding: 0, width: 0, height: 200) // 新增宽度约束消除歧义 navigationView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true navigationView.addSubview(titleLbl) titleLbl.anchor(top: navigationView.topAnchor, trailing: nil, bottom: nil, leading: navigationView.leadingAnchor, topPadding: 40, rightPadding: 0, bottomPadding: 0, leftPadding: 16, width: 50, height: 23) navigationView.addSubview(profileIV) profileIV.anchor(top: navigationView.topAnchor, trailing: nil, bottom: nil, leading: nil, topPadding: 80, rightPadding: 0, bottomPadding: 0, leftPadding: 0, width: 68, height: 68) profileIV.centerXAnchor.constraint(equalTo: navigationView.centerXAnchor).isActive = true navigationView.addSubview(profileNameLbl) profileNameLbl.anchor(top: profileIV.bottomAnchor, trailing: nil, bottom: nil, leading: nil, topPadding: 10, rightPadding: 0, bottomPadding: 0, leftPadding: 0, width: 0, height: 27) profileNameLbl.centerXAnchor.constraint(equalTo: navigationView.centerXAnchor).isActive = true
备选方案(如果你非要手动设置contentSize)
如果坚持手动控制可滚动区域,记得同时设置宽度:
scrollView.contentSize = CGSize(width: view.bounds.width, height: 1000)
这样scrollView的content宽度明确了,navigationView绑定scrollView的leading/trailing约束就能生效,不会再有歧义。
额外小提示
以后处理UIScrollView布局时,尽量依赖AutoLayout自动计算contentSize——只要子视图的约束能形成完整的布局链(从content的top到bottom、left到right都有明确约束),系统会自动算出正确的可滚动区域,比手动设置更可靠,尤其是在屏幕旋转这类场景下。
内容的提问来源于stack exchange,提问作者Ferry Adi Wijayanto

