以编程方式逐个添加视图

时间:2018-01-29 06:19:29

标签: ios swift uiscrollview autolayout

我是Swift的新手(使用4版本)。 我有HTML文本,里面可以包含图片链接。

some text 
<img src=""/>
some text

我想让内容可滚动,所以我将容器(简单的UIView)包装到UIScrollview

然后我将HTML文本解析为部分:&#34; text&#34;和&#34;图像链接&#34;到一个数组(数据和类型)。 然后迭代我观察的那个数组,如果类型是文本 - 我输入带有约束的标签:

如果它是容器的第一个元素,那么left,top,right和bottom匹配。 如果没有,则top匹配容器中的前一个视图的底部(如链)。

但由于某种原因,它不起作用。 我究竟做错了什么? 我把我的代码:

    var lastView = containerView!
    var label : UILabel
    var imageView : UIImageView

    for item in articleContent {
        if (item.type == RenderDetailBlogObject.TYPE_TEXT) {
            label = UILabel()

            label.numberOfLines = 0
            label.attributedText = item.data.html2AttributedString
            containerView.addSubview(label)

            label.translatesAutoresizingMaskIntoConstraints = false

            NSLayoutConstraint.activate([
                label.leftAnchor.constraint(equalTo: containerView.leftAnchor),
                label.rightAnchor.constraint(equalTo: containerView.rightAnchor),
                ])

            if (lastView == containerView) {
                print("ADDING LABEL lastView == containerView")
                label.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 0.0).isActive = true
            } else {
                  print("ADDING LABEL lastView != containerView")
                 label.topAnchor.constraint(equalTo: lastView.bottomAnchor, constant: 0.0).isActive = true
            }

            lastView = label
        } else {
            imageView = UIImageView()

            imageView.sd_setImage(with: URL(string: item.data))
            containerView.addSubview(imageView)

            imageView.translatesAutoresizingMaskIntoConstraints = false

            NSLayoutConstraint.activate([

                imageView.leftAnchor.constraint(equalTo: containerView.leftAnchor),
                imageView.rightAnchor.constraint(equalTo: containerView.rightAnchor),
                ])

            if (lastView == containerView) {
                print("ADDING AN IMAGE lastView == containerView")
                 imageView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 0.0).isActive = true
            } else {
                 print("ADDING AN IMAGE lastView != containerView")
                imageView.topAnchor.constraint(equalTo: lastView.bottomAnchor, constant: 0.0).isActive = true
            }

            lastView = imageView
        }

        lastView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: 0.0)
    }

编辑: 代码似乎是正确的,视图正确添加,但禁止滚动视图。

我测试了约束(中心Y - 为它添加了200多个范围并且它开始滚动,但它的硬编码值,所以它可能有更合法的解决方案吗?) 如果没有这种限制,它就会给出错误并且根本不起作用。

enter image description here

2 个答案:

答案 0 :(得分:2)

我相信这条线是你的麻烦来源:

lastView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: 0.0)

现在,当您遍历项目时,您将每个label / imageView约束为将底部锚点约束到containerView的底部。我希望这会导致不满意的约束警告(检查你的控制台)。您希望约束添加到容器的最后一个label / imageView的底部。因此,只需将该行移出其后面的for循环:

var lastView = containerView!
var label : UILabel
var imageView : UIImageView

for item in articleContent {
    if (item.type == RenderDetailBlogObject.TYPE_TEXT) {
        label = UILabel()

        label.numberOfLines = 0
        label.attributedText = item.data.html2AttributedString
        containerView.addSubview(label)

        label.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            label.leftAnchor.constraint(equalTo: containerView.leftAnchor),
            label.rightAnchor.constraint(equalTo: containerView.rightAnchor),
            ])

        if lastView == containerView {
            print("ADDING LABEL lastView == containerView")
            label.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 0.0).isActive = true
        } else {
              print("ADDING LABEL lastView != containerView")
            label.topAnchor.constraint(equalTo: lastView.bottomAnchor, constant: 0.0).isActive = true
        }

        lastView = label
    } else {
        imageView = UIImageView()

        imageView.sd_setImage(with: URL(string: item.data))
        containerView.addSubview(imageView)

        imageView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([

            imageView.leftAnchor.constraint(equalTo: containerView.leftAnchor),
            imageView.rightAnchor.constraint(equalTo: containerView.rightAnchor),
            ])

        if lastView == containerView {
            print("ADDING AN IMAGE lastView == containerView")
            imageView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 0.0).isActive = true
        } else {
            print("ADDING AN IMAGE lastView != containerView")
            imageView.topAnchor.constraint(equalTo: lastView.bottomAnchor, constant: 0.0).isActive = true
        }

        lastView = imageView
    }
}
// Constrain the bottom only for the last view that was added
lastView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: 0.0).isActive = true

如果根据此答案进行重构无法解决滚动问题,我建议您查看containerViewscrollView之间的约束 - 您可以使用this answer作为参考。< / p>

答案 1 :(得分:1)

或许更清晰的方法是在您的滚动视图中使用UIStackView,以便您可以将任何其他视图作为子视图添加到UIStackView。这样你就不必自己处理约束。

因此,您的视图层次结构应类似于下面的内容。

->UIView
    ->UIScrollView
        ->UIView
            ->UIStackView

然后将约束添加到scrollView,作为左上角 - 右下角

另外将UIView添加到UIScrollView作为包装器视图,并将约束添加为左上角 - 右下角,并为此包装器视图添加另外两个约束相对于主视图,等于宽度等于高度。这将使UIScrollView与动态高度相关,在此post

中有更多信息

现在向堆栈视图添加约束,因为左上角 - 右下角也添加了带插座连接的高度约束。

现在,当您向堆栈视图添加任何视图时,只需更改UIStackView的高度常量,您的UIScrollView将自动展开。