使用可视格式语言以编程方式将子视图添加到 ScrollView

Add subviews programmatically to ScrollView using Visual Format Language

滚动视图 - 以编程方式布局 - swift 3

亲爱的朋友们: 我希望有人能在我的大脑被烧毁之前修改这个项目并帮助我。提前致谢。

任务:水平滚动 - 布置一个包含 4 个图像的数组,正方形为 240 x 240,间距为 20。滚动视图的约束直接在故事板中设置,但图像子视图是使用可视化格式语言以编程方式添加的。滚动的内容大小假设由这个约束完成。

我所做的:设置图像数组,以编程方式创建 de ImageView 并使用 for in 循环添加数组。使用视觉格式创建约束。可以在本文中找到执行此操作的方法:http://www.apeth.com/iOSBook/ch20.html.

此处link到GitHub中的项目 https://github.com/ricardovaldes/soloScrollEjercicio

Constraints for the ScrollView added directly in the storyboard.

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var myScroll: UIScrollView!

    var carsArray = [UIImage]()
    var constraints = [NSLayoutConstraint]()

    override func viewDidLoad() {
        super.viewDidLoad()

        carsArray = [#imageLiteral(resourceName: "fasto1"), #imageLiteral(resourceName: "fasto2"), #imageLiteral(resourceName: "fasto3"), #imageLiteral(resourceName: "fasto4")]

        var const = [NSLayoutConstraint]()
        var views: [String: UIView]
        var previous: UIImageView? = nil

        for index in 0..<carsArray.count{
            let newImageView = UIImageView()
            newImageView.image  = carsArray[index]
            newImageView.translatesAutoresizingMaskIntoConstraints = false
            myScroll.addSubview(newImageView)
            self.myScroll.setNeedsLayout()


            views = ["newImageView": newImageView, "myScroll": myScroll]

            if previous == nil{
                const.append(contentsOf: NSLayoutConstraint.constraints(withVisualFormat: "H:|[newImageView(240)]",  metrics: nil, views: views))
            }
            else{
                const.append(contentsOf: NSLayoutConstraint.constraints(withVisualFormat: "H:[previous]-20-[newImageView(240)]", metrics: nil, views: ["newImageView": newImageView, "previous": previous!]))
            }

            previous = newImageView

            const.append(contentsOf: NSLayoutConstraint.constraints(withVisualFormat: "H:[previous]|", metrics: nil, views: ["previous": newImageView]))

            const.append(contentsOf: NSLayoutConstraint.constraints(withVisualFormat: "V:|[newImageView(240)]|", metrics: nil, views: views))

        }
        NSLayoutConstraint.activate(const)
    }
}

尽管我尝试了很多组合,但我还是出现了同样的错误:

2018-04-29 21:24:34.347466-0500 soloScrollEjercicio[12002:1665919] [LayoutConstraints] Unable to simultaneously satisfy constraints.

每一轮循环,你添加一个右侧引脚约束来为每个新的滚动视图 添加了imageView,但是彼此之间有20个点。

 |-previous-20-newOne-|                                ** second round loop **
                     -20-newOne'-|                     ** third round loop  **

这打破了 imageView 宽度 (240) 约束

一种处理方法: 仅将右侧引脚约束添加到 最后一个 imageView。

主情节提要中的滚动视图约束也中断了。

+-------------------+
|          |        |
|-scroll view (240)-|

与超级视图垂直间距的底部不应存在。它会 break scroll view height(240),删掉就好了

也许你应该试试:

  • 将其约束优先级设置为 999,或其他不等于的值 1000
  • 取消选中已安装的框
  • 删除它


现在,您的滚动视图应该没问题了。


p.s。我发现你的参考书是基于iOS 6? 2018年,从iOS10或iOS11开始可能是更好的选择。

祝你黑客愉快:)