我正在尝试以编程方式创建一个视图控制器,它将以可滚动的方式布置子视图。我试图在UIScrollView中使用AutoLayout,并在这方面阅读了所有技术说明和SO答案。但我无法做到这一点 - 似乎在创作/使用或UIScrollView中存在一些细微差别,我在这里缺少。
我的代码在下面,我看到的输出也显示在下面的图片中。
我的期望是我会看到占据整个屏幕的棕色和绿色条纹(子视图)。我知道我必须指定子视图的高度,但我不明白为什么水平大小调整不起作用。如果我没有指定水平尺寸,我希望我的子视图会被拉伸并占据屏幕的宽度,但它不会这样做。
这是我的控制器的代码。
class ScrollableRowHeadersViewController : UIViewController {
var scrollView : UIScrollView!
override func loadView() {
self.view = UIView(frame: CGRectZero)
scrollView = UIScrollView()
scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(scrollView)
scrollView.backgroundColor = UIColor.blueColor()
self.view.addVisualConstraint("H:|-0-[scrollView]-0-|", viewsDict: ["scrollView" : scrollView])
self.view.addVisualConstraint("V:|-0-[scrollView]-0-|", viewsDict: ["scrollView" : scrollView])
self.view.contentMode = UIViewContentMode.Redraw
}
//load all the subviews after the main view and scrollview loaded.
override func viewDidLoad() {
var viewsDict = [String: UIView]()
var vertical_constraints = "V:|"
scrollView.autoresizesSubviews = true
for i in 1...100 {
var subview = UIView()
subview.setTranslatesAutoresizingMaskIntoConstraints(false)
subview.backgroundColor = (i%2 == 0 ? UIColor.brownColor() : UIColor.greenColor())
viewsDict["subview_\(i)"] = subview
self.scrollView.addSubview(subview)
vertical_constraints += "[subview_\(i)(==50)]"
self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[subview_\(i)]|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
}
vertical_constraints += "|"
self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(vertical_constraints, options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
}
}
这是水平约束设置为H的输出:| [subview_(i)] |
这是水平约束设置为H的输出:| [subview_(i)(== 100)] |
在任何一种情况下,我都希望在整个屏幕宽度上看到交替的棕色和绿色条纹。
我错过了什么?在此先感谢您的帮助。
答案 0 :(得分:10)
经过更多的痛苦和阅读后,这种行为的原因和答案变得更加清晰。在this SO question也有很好的描述。我希望技术说明更加英语,但@rdelmar和@Rob非常清楚地解释说“ContentView上的约束用于设置scrollView的contentSize ”。
这是修改后的代码和结果(我认为是正确的解决方案)。我的视图层次现在是这样的: ViewController - > UIView(mainView) - > UIScrollVIew - > UIView(contentView) - > UIViews(亚视图)
contentView和mainView之间存在额外的宽度限制。此外,所有子视图都会添加到contentView,而不是直接添加到scrollView。
class ScrollableRowHeadersViewController : UIViewController {
var scrollView : UIScrollView!
var contentView : UIView!
override func loadView() {
super.loadView()
self.view = UIView(frame: CGRectZero)
scrollView = UIScrollView(frame:CGRectZero)
scrollView.sizeToFit()
scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(scrollView)
scrollView.backgroundColor = UIColor.blueColor()
contentView = UIView()
contentView.setTranslatesAutoresizingMaskIntoConstraints(false)
contentView.backgroundColor = UIColor.redColor()
scrollView.addSubview(contentView)
self.view.addVisualConstraint("H:|-0-[scrollView]-0-|", viewsDict: ["scrollView" : scrollView])
self.view.addVisualConstraint("V:|-0-[scrollView]-0-|", viewsDict: ["scrollView" : scrollView])
self.view.addVisualConstraint("H:|[contentView]|", viewsDict: ["contentView" : contentView])
self.view.addVisualConstraint("V:|[contentView]|", viewsDict: ["contentView" : contentView])
//make the width of content view to be the same as that of the containing view.
self.view.addVisualConstraint("H:[contentView(==mainView)]", viewsDict: ["contentView" : contentView, "mainView" : self.view])
self.view.contentMode = UIViewContentMode.Redraw
}
//load all the subviews after the main view and scrollview loaded.
override func viewDidLoad() {
var viewsDict = [String: UIView]()
viewsDict["contentView"] = contentView
viewsDict["super"] = self.view
var vertical_constraints = "V:|"
for i in 1...50 {
var subview = UIView()
subview.setTranslatesAutoresizingMaskIntoConstraints(false)
subview.backgroundColor = (i%2 == 0 ? UIColor.brownColor() : UIColor.greenColor())
viewsDict["subview_\(i)"] = subview
contentView.addSubview(subview)
vertical_constraints += "[subview_\(i)(==50)]"
self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[subview_\(i)]|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
}
vertical_constraints += "|"
self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(vertical_constraints, options: NSLayoutFormatOptions.AlignAllLeft, metrics: nil, views: viewsDict))
}
}
这是我期望的输出:
答案 1 :(得分:1)
使用滚动视图,“|”指的是contentView,而不是滚动视图,因此通过将子视图设置为100,您将告诉contentView为100点宽(同样在第一种情况下,因为您没有设置宽度,您获得0宽度contentView)。你应该这样做,
self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[subview_\(i)(==width)]|", options: NSLayoutFormatOptions(0), metrics:["width": self.scrollView.frame.size.width], views: viewsDict))