无法使用纯自动布局约束创建 UIScrollerView
Cannot create UIScrollerView with pure auto layout constraints
我精简了我的代码,以便于理解。
假设您有一个控制器,并且想要使用纯自动布局添加一个简单的滚动条。
您可以调用我的功能工具(如下提供):
// Create scroll view
let strip = addStripCategoryTo(view)
// Attach it to the view, vertically and horizontally
strip.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
strip.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = true
// The function
func addStripCategoryTo(parent: UIView) -> UIView {
let h:CGFloat = 128
let w = 2*h/3
let n = 5
let width = w * CGFloat(n)
let height = h
// Scroll view
let scrollview = UIScrollView()
parent.addSubview(scrollview)
scrollview.scrollEnabled = true
scrollview.translatesAutoresizingMaskIntoConstraints = false
scrollview.widthAnchor .constraintEqualToAnchor(parent.widthAnchor).active = true
scrollview.heightAnchor.constraintEqualToConstant(h).active = true
scrollview.layer.borderWidth = 2
scrollview.layer.borderColor = UIColor.greenColor().CGColor
scrollview.backgroundColor = UIColor.brownColor()
// Scroll view content
let contentView = UIView() //frame:CGRect(origin: CGPointZero, size:CGSize(width: width, height: height)))
scrollview.addSubview(contentView)
contentView.backgroundColor = UIColor.redColor()
contentView.layer.borderWidth = 10
contentView.layer.borderColor = UIColor.blueColor().CGColor
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.centerYAnchor.constraintEqualToAnchor(scrollview.centerYAnchor).active = true
contentView.widthAnchor .constraintEqualToConstant(width).active = true
contentView.heightAnchor.constraintEqualToConstant(height).active = true
return scrollview
}
不幸的是,我不能水平滚动,截图如下:
我错过了什么?
你的约束应该是这样的,
滚动视图 - 顶部、底部、前导、尾随
ContentView - 顶部、底部、前导、尾随、固定宽度、在容器中垂直居中(中心 y)
并且您的内容视图的宽度应大于屏幕宽度,然后您还可以水平滚动
希望这会有所帮助:)
打算试一试并回答这个问题,看看是否有帮助。
编辑
回答问题更好,旧答案已删除:
添加这两行应该可以水平滚动:
contentView.leadingAnchor.constraintEqualToAnchor(scrollview.leadingAnchor).active = true contentView.trailingAnchor.constraintEqualToAnchor(scrollview.trailingAnchor).active = true
问题是没有这两个约束,scrollView 不知道它的 contentSize,因此不会滚动,即使你给了 contentView 一个特定的宽度。您需要让 scrollView 知道 contentView 从哪里开始和结束,这两个约束将帮助 scrollView 知道 contentsView 的宽度有多大。如果不是,则 scrollView 的 contentSize 将与设备的宽度保持相同,并且 contentView 将显示在屏幕外,因为它的宽度大于设备的屏幕。
希望这对您有所帮助。
函数的完整代码
func addStripCategoryTo(parent: UIView)-> UIView {
let h:CGFloat = 128
let w = 2*h/3
let n = 5
let width = w * CGFloat(n)
let height = h
// Scroll view
let scrollview = UIScrollView()
parent.addSubview(scrollview)
scrollview.scrollEnabled = true
scrollview.translatesAutoresizingMaskIntoConstraints = false
scrollview.leadingAnchor.constraintEqualToAnchor(parent.leadingAnchor).active = true
scrollview.trailingAnchor.constraintEqualToAnchor(parent.trailingAnchor).active = true
scrollview.widthAnchor .constraintEqualToAnchor(parent.widthAnchor).active = true
scrollview.heightAnchor.constraintEqualToConstant(h).active = true
scrollview.layer.borderWidth = 2
scrollview.layer.borderColor = UIColor.greenColor().CGColor
scrollview.backgroundColor = UIColor.brownColor()
// Scroll view content
let contentView = UIView() //frame:CGRect(origin: CGPointZero, size:CGSize(width: width, height: height)))
scrollview.addSubview(contentView)
contentView.backgroundColor = UIColor.redColor()
contentView.layer.borderWidth = 10
contentView.layer.borderColor = UIColor.blueColor().CGColor
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.centerYAnchor.constraintEqualToAnchor(scrollview.centerYAnchor).active = true
contentView.leadingAnchor.constraintEqualToAnchor(scrollview.leadingAnchor).active = true
contentView.trailingAnchor.constraintEqualToAnchor(scrollview.trailingAnchor).active = true
contentView.widthAnchor.constraintEqualToConstant(width).active = true
contentView.heightAnchor.constraintEqualToConstant(height).active = true
return scrollview
}
这是我的问题的解决方案。我提供了一个解决问题的工具功能如下:
func setScrollViewConstraints(scrollView: UIScrollView, contentView:UIView, multiplier m:(width:CGFloat, height:CGFloat)=(1, 1)) {
guard let scrollViewParent = scrollView.superview else {
assert(false, "setScrollViewConstraints() requires the scrollview to have a superview")
return
}
guard let contentViewParent = contentView.superview else {
assert(false, "setScrollViewConstraints() requires the contentView to have a superview")
return
}
guard contentViewParent == scrollView else {
assert(false, "setScrollViewConstraints() requires the contentView to have a superview being the scrollView")
return
}
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.widthAnchor .constraintEqualToAnchor(scrollViewParent.widthAnchor, multiplier: m.width ).active = true
scrollView.heightAnchor .constraintEqualToAnchor(scrollViewParent.heightAnchor, multiplier: m.height).active = true
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.leftAnchor .constraintEqualToAnchor(contentViewParent.leftAnchor ).active = true
contentView.rightAnchor .constraintEqualToAnchor(contentViewParent.rightAnchor ).active = true
contentView.topAnchor .constraintEqualToAnchor(contentViewParent.topAnchor ).active = true
contentView.bottomAnchor.constraintEqualToAnchor(contentViewParent.bottomAnchor ).active = true
/*
// Pre-iOS 9 version
let views = [
"scrollView":scrollview,
"contentView":contentView
]
parent.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options:[], metrics: [:], views:views))
parent.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options:[], metrics: [:], views:views))
scrollview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[contentView]|", options:[], metrics: [:], views:views))
scrollview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[contentView]|", options:[], metrics: [:], views:views))
*/
}
像这样使用它使滚动视图的宽度为超级视图的 100% 和其高度的 1/4:
func addStripCategoryTo(parent: UIView) -> UIView {
// Scroll view
let scrollview = UIScrollView()
parent.addSubview(scrollview)
scrollview.backgroundColor = UIColor.brownColor()
scrollview.layer.borderWidth = 2
scrollview.layer.borderColor = UIColor.greenColor().CGColor
// Scroll view content
let contentView = UIImageView()
contentView.image = UIImage(named: "cover-0.jpeg")
scrollview.addSubview(contentView)
contentView.backgroundColor = UIColor.redColor()
contentView.layer.borderWidth = 10
contentView.layer.borderColor = UIColor.blueColor().CGColor
// Apply constraints
setScrollViewConstraints(scrollview, contentView:contentView, multiplier: (1, 0.25))
return scrollview
}
我精简了我的代码,以便于理解。
假设您有一个控制器,并且想要使用纯自动布局添加一个简单的滚动条。
您可以调用我的功能工具(如下提供):
// Create scroll view
let strip = addStripCategoryTo(view)
// Attach it to the view, vertically and horizontally
strip.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
strip.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = true
// The function
func addStripCategoryTo(parent: UIView) -> UIView {
let h:CGFloat = 128
let w = 2*h/3
let n = 5
let width = w * CGFloat(n)
let height = h
// Scroll view
let scrollview = UIScrollView()
parent.addSubview(scrollview)
scrollview.scrollEnabled = true
scrollview.translatesAutoresizingMaskIntoConstraints = false
scrollview.widthAnchor .constraintEqualToAnchor(parent.widthAnchor).active = true
scrollview.heightAnchor.constraintEqualToConstant(h).active = true
scrollview.layer.borderWidth = 2
scrollview.layer.borderColor = UIColor.greenColor().CGColor
scrollview.backgroundColor = UIColor.brownColor()
// Scroll view content
let contentView = UIView() //frame:CGRect(origin: CGPointZero, size:CGSize(width: width, height: height)))
scrollview.addSubview(contentView)
contentView.backgroundColor = UIColor.redColor()
contentView.layer.borderWidth = 10
contentView.layer.borderColor = UIColor.blueColor().CGColor
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.centerYAnchor.constraintEqualToAnchor(scrollview.centerYAnchor).active = true
contentView.widthAnchor .constraintEqualToConstant(width).active = true
contentView.heightAnchor.constraintEqualToConstant(height).active = true
return scrollview
}
不幸的是,我不能水平滚动,截图如下:
我错过了什么?
你的约束应该是这样的,
滚动视图 - 顶部、底部、前导、尾随
ContentView - 顶部、底部、前导、尾随、固定宽度、在容器中垂直居中(中心 y)
并且您的内容视图的宽度应大于屏幕宽度,然后您还可以水平滚动 希望这会有所帮助:)
打算试一试并回答这个问题,看看是否有帮助。
编辑 回答问题更好,旧答案已删除:
添加这两行应该可以水平滚动:
contentView.leadingAnchor.constraintEqualToAnchor(scrollview.leadingAnchor).active = true contentView.trailingAnchor.constraintEqualToAnchor(scrollview.trailingAnchor).active = true
问题是没有这两个约束,scrollView 不知道它的 contentSize,因此不会滚动,即使你给了 contentView 一个特定的宽度。您需要让 scrollView 知道 contentView 从哪里开始和结束,这两个约束将帮助 scrollView 知道 contentsView 的宽度有多大。如果不是,则 scrollView 的 contentSize 将与设备的宽度保持相同,并且 contentView 将显示在屏幕外,因为它的宽度大于设备的屏幕。
希望这对您有所帮助。
函数的完整代码
func addStripCategoryTo(parent: UIView)-> UIView {
let h:CGFloat = 128
let w = 2*h/3
let n = 5
let width = w * CGFloat(n)
let height = h
// Scroll view
let scrollview = UIScrollView()
parent.addSubview(scrollview)
scrollview.scrollEnabled = true
scrollview.translatesAutoresizingMaskIntoConstraints = false
scrollview.leadingAnchor.constraintEqualToAnchor(parent.leadingAnchor).active = true
scrollview.trailingAnchor.constraintEqualToAnchor(parent.trailingAnchor).active = true
scrollview.widthAnchor .constraintEqualToAnchor(parent.widthAnchor).active = true
scrollview.heightAnchor.constraintEqualToConstant(h).active = true
scrollview.layer.borderWidth = 2
scrollview.layer.borderColor = UIColor.greenColor().CGColor
scrollview.backgroundColor = UIColor.brownColor()
// Scroll view content
let contentView = UIView() //frame:CGRect(origin: CGPointZero, size:CGSize(width: width, height: height)))
scrollview.addSubview(contentView)
contentView.backgroundColor = UIColor.redColor()
contentView.layer.borderWidth = 10
contentView.layer.borderColor = UIColor.blueColor().CGColor
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.centerYAnchor.constraintEqualToAnchor(scrollview.centerYAnchor).active = true
contentView.leadingAnchor.constraintEqualToAnchor(scrollview.leadingAnchor).active = true
contentView.trailingAnchor.constraintEqualToAnchor(scrollview.trailingAnchor).active = true
contentView.widthAnchor.constraintEqualToConstant(width).active = true
contentView.heightAnchor.constraintEqualToConstant(height).active = true
return scrollview
}
这是我的问题的解决方案。我提供了一个解决问题的工具功能如下:
func setScrollViewConstraints(scrollView: UIScrollView, contentView:UIView, multiplier m:(width:CGFloat, height:CGFloat)=(1, 1)) {
guard let scrollViewParent = scrollView.superview else {
assert(false, "setScrollViewConstraints() requires the scrollview to have a superview")
return
}
guard let contentViewParent = contentView.superview else {
assert(false, "setScrollViewConstraints() requires the contentView to have a superview")
return
}
guard contentViewParent == scrollView else {
assert(false, "setScrollViewConstraints() requires the contentView to have a superview being the scrollView")
return
}
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.widthAnchor .constraintEqualToAnchor(scrollViewParent.widthAnchor, multiplier: m.width ).active = true
scrollView.heightAnchor .constraintEqualToAnchor(scrollViewParent.heightAnchor, multiplier: m.height).active = true
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.leftAnchor .constraintEqualToAnchor(contentViewParent.leftAnchor ).active = true
contentView.rightAnchor .constraintEqualToAnchor(contentViewParent.rightAnchor ).active = true
contentView.topAnchor .constraintEqualToAnchor(contentViewParent.topAnchor ).active = true
contentView.bottomAnchor.constraintEqualToAnchor(contentViewParent.bottomAnchor ).active = true
/*
// Pre-iOS 9 version
let views = [
"scrollView":scrollview,
"contentView":contentView
]
parent.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options:[], metrics: [:], views:views))
parent.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options:[], metrics: [:], views:views))
scrollview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[contentView]|", options:[], metrics: [:], views:views))
scrollview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[contentView]|", options:[], metrics: [:], views:views))
*/
}
像这样使用它使滚动视图的宽度为超级视图的 100% 和其高度的 1/4:
func addStripCategoryTo(parent: UIView) -> UIView {
// Scroll view
let scrollview = UIScrollView()
parent.addSubview(scrollview)
scrollview.backgroundColor = UIColor.brownColor()
scrollview.layer.borderWidth = 2
scrollview.layer.borderColor = UIColor.greenColor().CGColor
// Scroll view content
let contentView = UIImageView()
contentView.image = UIImage(named: "cover-0.jpeg")
scrollview.addSubview(contentView)
contentView.backgroundColor = UIColor.redColor()
contentView.layer.borderWidth = 10
contentView.layer.borderColor = UIColor.blueColor().CGColor
// Apply constraints
setScrollViewConstraints(scrollview, contentView:contentView, multiplier: (1, 0.25))
return scrollview
}