如何通过循环swift 5在scrollview内为imageView设置TrailingAnchor.constraint

问题描述 投票:0回答:2

这是通过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()
        }
    }

这是输出:

enter image description here

显示完美。现在,如果我将页眉向下滑动到屏幕上(因为它是可伸缩的页眉),则第二张图像也会与第一张图像一起显示,如下所示:

enter image description here

之所以这样,是因为图像视图没有trailingAnchor.constraint。所以我的问题是,当尚未创建下一个图像视图时,是否可以在循环内设置带有图像视图的尾锚?如果可以,怎么办?任何建议将不胜感激。预先感谢。

我的故事板:

enter image description here

SAMPLE PROJECT LINK

ios swift constraints nslayoutconstraint ios-autolayout
2个回答
1
投票

编辑

虽然我仍然建议为imageViews使用堆栈视图,但这不是问题。

查看示例项目后,您可以用一行代码来解决问题。

在您的循环中:

    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,然后将图像视图添加为已排列的子视图。

这里是在“普通”视图中使用滚动视图的示例,但是它将直接转换为在表头视图中使用它的直接视图:

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
            }
        }

    }

}

这是在情节提要中的设置方法:

enter image description here

滚动视图被约束在顶部/前导/尾随,高度为150

堆栈视图被限制在滚动视图的“内容布局指南”的所有四个侧面,其高度等于滚动视图的“框架布局指南”的高度。宽度限制为200(只是我选择的一个随机数,它比视图窄),但是该约束具有Priority of 250,这使它可以在添加排列的子视图时自动展开。


0
投票

您可以将collectionView与true一起使用。然后,您可以相对于滚动的内容偏移量在代码中动态更改约束,以产生粘性效果。

                     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
            }
        }

0
投票

您可以将collectionView与true一起使用。然后,您可以相对于滚动的内容偏移量在代码中动态更改约束以产生粘性效果。

                     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
            }
        }
© www.soinside.com 2019 - 2024. All rights reserved.