如何通过循环 swift 5 为滚动视图内的 imageView 设置 trailingAnchor.constraint

Posted

技术标签:

【中文标题】如何通过循环 swift 5 为滚动视图内的 imageView 设置 trailingAnchor.constraint【英文标题】:How to set trailingAnchor.constraint for imageView inside scrollview through loop swift 5 【发布时间】:2019-12-02 13:58:53 【问题描述】:

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

这是输出:

显示完美。现在,如果我将标题向下滑动到屏幕(因为它是有弹性的标题),第二张图片也会与第一张图片一起显示,如下所示:

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

我的故事板:

SAMPLE PROJECT LINK

【问题讨论】:

你不能通过部分插入和布局上的间距来设置它吗?这就是它们存在的原因 @Pancho 感谢您的评论。请您详细说明一下吗? 对不起,我只是简单地红色了你的标题,错过了你正在使用的部分 UIScrollView 在这种情况下你需要设置一个约束。我在想你正在使用UICollectionView,在这种情况下,我上面的评论是有道理的。 不太清楚你在做什么...你在“折扣价”标签上方有滚动视图吗?当您“向下滑动”时,您是否更改了该滚动视图的高度约束? 好的,请稍等,让我用更多图形更新我的问题。 【参考方案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
            
        

    


这是它在故事板中的设置方式:

滚动视图被限制在顶部/前/后,高度为 150

堆栈视图的所有 4 个边都被限制在滚动视图的内容布局指南中,高度等于滚动视图的框架布局指南高度。宽度被限制为 200(只是我选择的一个比视图窄的随机数),但该约束有一个 Priority of 250 - 这允许它在您添加排列的子视图时自动扩展。

【讨论】:

感谢您的回答。让我试一试。我已经添加了一个带有问题的示例项目链接。想看的可以去看看。 天啊!我正在寻找这个。非常感谢,伙计。你又节省了我的时间。 :)【参考方案2】:

您可以将 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
            
        

【讨论】:

以上是关于如何通过循环 swift 5 为滚动视图内的 imageView 设置 trailingAnchor.constraint的主要内容,如果未能解决你的问题,请参考以下文章

如何通过向它们添加组件来使滚动器内的视图自动调整大小? - 斯威夫特 3

IOS中水平滚动视图问题内的滑块

滚动视图没有重力。如何使滚动视图内的内容为中心

使用swift在scrollview内的stackview中更改uibutton中的标题

通过点击状态栏滚动到顶部 TableView 不起作用(有许多子视图)SWIFT

如何在 SWIFT 中更改 ViewController 后保留集合视图滚动位置