如何通过循环 swift 为 scrollview 内的 imageView 设置 trailingAnchor.constraint 5
How to set trailingAnchor.constraint for imageView inside scrollview through loop swift 5
这就是我通过 for 循环在滚动视图中显示图像视图的方式:
func addPageController() {
let imgArray = ["AquariumBG", "PaludariumBG", "TerrariumBG"]
let scrollContentViewWidthAnchor = scrollContentView.widthAnchor.constraint(equalTo: headerScrollView.widthAnchor, constant:0)
scrollContentViewWidthAnchor.isActive = true
for (index, item) in imgArray.enumerated() {
let imgView = UIImageView()
imgView.contentMode = .scaleAspectFill
imgView.image = UIImage(named: item)
let xPos = CGFloat(index) * UIScreen.main.bounds.size.width
scrollContentView.addSubview(imgView)
scrollContentView.translatesAutoresizingMaskIntoConstraints = false
scrollContentView.topAnchor.constraint(equalTo: headerScrollView.topAnchor, constant: 0).isActive = true
scrollContentView.bottomAnchor.constraint(equalTo: headerScrollView.bottomAnchor, constant: 0).isActive = true
scrollContentView.leadingAnchor.constraint(equalTo: headerScrollView.leadingAnchor, constant: 0).isActive = true
scrollContentViewWidthAnchor.constant = xPos
scrollContentView.setNeedsLayout()
scrollContentView.layoutIfNeeded()
imgView.translatesAutoresizingMaskIntoConstraints = false
imgView.topAnchor.constraint(equalTo: scrollContentView.topAnchor, constant: 0).isActive = true
imgView.bottomAnchor.constraint(equalTo: scrollContentView.bottomAnchor, constant: 0).isActive = true
imgView.widthAnchor.constraint(equalToConstant: headerScrollView.frame.size.width).isActive = true
imgView.leadingAnchor.constraint(equalTo: scrollContentView.leadingAnchor, constant: xPos).isActive = true
imgView.widthAnchor.constraint(equalToConstant: headerScrollView.frame.size.width).isActive = true
imgView.setNeedsLayout()
imgView.layoutIfNeeded()
}
}
这是输出:
显示完美。现在,如果我将 header 向下滑动到屏幕(因为它是有弹性的 header),第二张图片也会与第一张图片一起显示,如下所示:
这是因为图片浏览量没有trailingAnchor.constraint
。所以我的问题是,当下一个图像视图尚未创建时,是否可以在循环内使用图像视图设置尾随锚点?如果是这样怎么办?任何建议将不胜感激。提前致谢。
我的故事板:
You can use collectionView with pagination as true. And then a you can change the constraints dynamically in the code in respect to the scrolled content-offset to give sticky effect.
or
* 在此代码中,缺少尾随约束并不是其背后的唯一原因。你可以给你的图像一个宽度限制。您应该将图像的前导约束赋予它之前的图像的尾随约束,最后一张图像的尾随将作为容器视图
试试这个
for (index, item) in imgArray.enumerated() {
let imgView = UIImageView()
imgView.contentMode = .scaleAspectFill
imgView.image = UIImage(named: item)
var leadingView = scrollContentView
//get the view previous view to it
if index > 0 {
leadingView = scrollContentView.subviews[index - 1]
}
scrollContentView.addSubview(imgView)
imgView.translatesAutoresizingMaskIntoConstraints = false
imgView.topAnchor.constraint(equalTo: scrollContentView.topAnchor).isActive = true
imgView.bottomAnchor.constraint(equalTo: scrollContentView.bottomAnchor).isActive = true
imgView.widthAnchor.constraint(equalToConstant: headerScrollView.frame.size.width).isActive = true
imgView.leadingAnchor.constraint(equalTo: leadingView.trailingAnchor).isActive = true
//if this is last image set the trailingAnchor
if index == imgArray.count - 1 {
imgView.trailingAnchor.constraint(equalTo: scrollContentView.trailingAnchor).isActive = true
}
}
编辑
虽然我仍然建议为 imageView 使用堆栈视图,但这不是问题所在。
查看示例项目后,只需一行代码即可解决问题。
在你的循环中:
for (index, item) in imgArray.enumerated() {
let imgView = UIImageView()
// add this line
imgView.clipsToBounds = true
// continue with what you had...
imgView.contentMode = .scaleAspectFill
// etc...
}
编辑结束
我建议在滚动视图中放置一个 UIStackView
,然后将图像视图添加为排列的子视图。
这是一个在 "normal" 视图中使用滚动视图的示例,但它会直接转换为在 table header 视图中使用它:
class ScrollHeaderTestViewController: UIViewController {
@IBOutlet var theStackView: UIStackView!
@IBOutlet var theScrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
addPageController()
}
func addPageController() -> Void {
let imgArray = ["AquariumBG", "PaludariumBG", "TerrariumBG"]
imgArray.forEach { imgName in
if let img = UIImage(named: imgName) {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .scaleAspectFill
v.image = img
theStackView.addArrangedSubview(v)
v.widthAnchor.constraint(equalTo: theScrollView.frameLayoutGuide.widthAnchor).isActive = true
}
}
}
}
故事板中的设置方式如下:
滚动视图约束top/leading/trailing,高度为150
堆栈视图的所有 4 个边都被限制在滚动视图的内容布局指南中,高度等于滚动视图的框架布局指南的高度。宽度被限制为 200(只是我选择的一个比视图窄的随机数),但是该限制有一个 Priority of 250
——这允许它在您添加排列的子视图时 auto-expand。
这就是我通过 for 循环在滚动视图中显示图像视图的方式:
func addPageController() {
let imgArray = ["AquariumBG", "PaludariumBG", "TerrariumBG"]
let scrollContentViewWidthAnchor = scrollContentView.widthAnchor.constraint(equalTo: headerScrollView.widthAnchor, constant:0)
scrollContentViewWidthAnchor.isActive = true
for (index, item) in imgArray.enumerated() {
let imgView = UIImageView()
imgView.contentMode = .scaleAspectFill
imgView.image = UIImage(named: item)
let xPos = CGFloat(index) * UIScreen.main.bounds.size.width
scrollContentView.addSubview(imgView)
scrollContentView.translatesAutoresizingMaskIntoConstraints = false
scrollContentView.topAnchor.constraint(equalTo: headerScrollView.topAnchor, constant: 0).isActive = true
scrollContentView.bottomAnchor.constraint(equalTo: headerScrollView.bottomAnchor, constant: 0).isActive = true
scrollContentView.leadingAnchor.constraint(equalTo: headerScrollView.leadingAnchor, constant: 0).isActive = true
scrollContentViewWidthAnchor.constant = xPos
scrollContentView.setNeedsLayout()
scrollContentView.layoutIfNeeded()
imgView.translatesAutoresizingMaskIntoConstraints = false
imgView.topAnchor.constraint(equalTo: scrollContentView.topAnchor, constant: 0).isActive = true
imgView.bottomAnchor.constraint(equalTo: scrollContentView.bottomAnchor, constant: 0).isActive = true
imgView.widthAnchor.constraint(equalToConstant: headerScrollView.frame.size.width).isActive = true
imgView.leadingAnchor.constraint(equalTo: scrollContentView.leadingAnchor, constant: xPos).isActive = true
imgView.widthAnchor.constraint(equalToConstant: headerScrollView.frame.size.width).isActive = true
imgView.setNeedsLayout()
imgView.layoutIfNeeded()
}
}
这是输出:
显示完美。现在,如果我将 header 向下滑动到屏幕(因为它是有弹性的 header),第二张图片也会与第一张图片一起显示,如下所示:
这是因为图片浏览量没有trailingAnchor.constraint
。所以我的问题是,当下一个图像视图尚未创建时,是否可以在循环内使用图像视图设置尾随锚点?如果是这样怎么办?任何建议将不胜感激。提前致谢。
我的故事板:
You can use collectionView with pagination as true. And then a you can change the constraints dynamically in the code in respect to the scrolled content-offset to give sticky effect.
or
* 在此代码中,缺少尾随约束并不是其背后的唯一原因。你可以给你的图像一个宽度限制。您应该将图像的前导约束赋予它之前的图像的尾随约束,最后一张图像的尾随将作为容器视图
试试这个
for (index, item) in imgArray.enumerated() {
let imgView = UIImageView()
imgView.contentMode = .scaleAspectFill
imgView.image = UIImage(named: item)
var leadingView = scrollContentView
//get the view previous view to it
if index > 0 {
leadingView = scrollContentView.subviews[index - 1]
}
scrollContentView.addSubview(imgView)
imgView.translatesAutoresizingMaskIntoConstraints = false
imgView.topAnchor.constraint(equalTo: scrollContentView.topAnchor).isActive = true
imgView.bottomAnchor.constraint(equalTo: scrollContentView.bottomAnchor).isActive = true
imgView.widthAnchor.constraint(equalToConstant: headerScrollView.frame.size.width).isActive = true
imgView.leadingAnchor.constraint(equalTo: leadingView.trailingAnchor).isActive = true
//if this is last image set the trailingAnchor
if index == imgArray.count - 1 {
imgView.trailingAnchor.constraint(equalTo: scrollContentView.trailingAnchor).isActive = true
}
}
编辑
虽然我仍然建议为 imageView 使用堆栈视图,但这不是问题所在。
查看示例项目后,只需一行代码即可解决问题。
在你的循环中:
for (index, item) in imgArray.enumerated() {
let imgView = UIImageView()
// add this line
imgView.clipsToBounds = true
// continue with what you had...
imgView.contentMode = .scaleAspectFill
// etc...
}
编辑结束
我建议在滚动视图中放置一个 UIStackView
,然后将图像视图添加为排列的子视图。
这是一个在 "normal" 视图中使用滚动视图的示例,但它会直接转换为在 table header 视图中使用它:
class ScrollHeaderTestViewController: UIViewController {
@IBOutlet var theStackView: UIStackView!
@IBOutlet var theScrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
addPageController()
}
func addPageController() -> Void {
let imgArray = ["AquariumBG", "PaludariumBG", "TerrariumBG"]
imgArray.forEach { imgName in
if let img = UIImage(named: imgName) {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .scaleAspectFill
v.image = img
theStackView.addArrangedSubview(v)
v.widthAnchor.constraint(equalTo: theScrollView.frameLayoutGuide.widthAnchor).isActive = true
}
}
}
}
故事板中的设置方式如下:
滚动视图约束top/leading/trailing,高度为150
堆栈视图的所有 4 个边都被限制在滚动视图的内容布局指南中,高度等于滚动视图的框架布局指南的高度。宽度被限制为 200(只是我选择的一个比视图窄的随机数),但是该限制有一个 Priority of 250
——这允许它在您添加排列的子视图时 auto-expand。