StackView内的ScrollView

时间:2018-01-23 14:29:45

标签: ios swift swift4

我创建了垂直stackView: screenshot

在其中添加scrollView:

let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.contentMode = .scaleToFill
scrollView.clipsToBounds = true
self.addArrangedSubview(scrollView)
scrollView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
scrollView.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 0).isActive = true
scrollView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
scrollView.heightAnchor.constraint(equalToConstant: 100).isActive = true

在这个scrollView中,我添加了水平scrollView:

let imageStack = UIStackView()
imageStack.spacing = 5
imageStack.axis = .horizontal
imageStack.alignment = .center
imageStack.contentMode = .left
imageStack.distribution = .fillProportionally
imageStack.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(imageStack)
imageStack.heightAnchor.constraint(equalToConstant: 100).isActive = true
imageStack.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0).isActive = true
imageStack.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 0).isActive = true
imageStack.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0).isActive = true
imageStack.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 0).isActive = true

在此imageStack中我以编程方式插入图像。但是当有许多图像(超过4个)时,它们会相互叠加并且滚动不起作用。

是否可以在垂直stackView中使用水平滚动来排列子视图?或者除了垂直stackView宽度之外,不可能进行子视图的宽度?

EDITED

我试图编辑@beyowulf推荐的约束,但没有改变。看看screenshot。我向imageStack添加了5个图像,但只有部分可见,如果它们滚动并且没有工作

EDITED 看看我找到imageStack并在其中添加图像的代码:

let scrollView = self.dynamicView.subviews.first(where: {$0 is UIScrollView}) as! UIScrollView
let filesView = scrollView.subviews.first(where: { $0 is UIStackView } ) as! UIStackView
var filesCount = filesView.arrangedSubviews.count - 1

for image in images {
    let imgView = UIImageView()
    imgView.translatesAutoresizingMaskIntoConstraints = false
    let imageViewWidthConstraint = NSLayoutConstraint(item: imgView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 100)
    let imageViewHeightConstraint = NSLayoutConstraint(item: imgView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 100)
    imgView.addConstraints([imageViewWidthConstraint, imageViewHeightConstraint])
    imgView.contentMode = .scaleAspectFill
    imgView.clipsToBounds = true
    imgView.image = image
    imgView.isUserInteractionEnabled = true
    let swipeToTopRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(imageDelete))
    swipeToTopRecognizer.direction = .up
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped))
    imgView.addGestureRecognizer(tapRecognizer)
    imgView.addGestureRecognizer(swipeToTopRecognizer)
    filesView.insertArrangedSubview(imgView, at: filesCount)
    filesCount += 1
}

2 个答案:

答案 0 :(得分:1)

如果您的目标是iOS 11或更高版本,则可以使用UIScrollView的{​​{1}}和contentLayoutGuide来区分您希望约束滚动视图内容的时间或框架你的滚动视图。例如:

frameLayoutGuide

例如,您可以尝试:

scrollView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
scrollView.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 0).isActive = true
scrollView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
scrollView.heightAnchor.constraint(equalToConstant: 100).isActive = true

您正在添加更适合滚动视图框架的约束。在这里:

scrollView.frameLayoutGuide.heightAnchor.constraint(equalToConstant: 100).isActive = true
scrollView.frameLayoutGuide.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true

您正在添加更适合规定滚动视图内容大小的约束。

例如,您可以尝试:

imageStack.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0).isActive = true
imageStack.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 0).isActive = true
imageStack.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0).isActive = true
imageStack.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 0).isActive = true

话虽这么说,你添加的限制多于严格必要的约束,这些约束通常很糟糕,可能导致布局冲突。如果要向imageStack.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 0).isActive = true imageStack.leftAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leftAnchor, constant: 0).isActive = true imageStack.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: 0).isActive = true imageStack.rightAnchor.constraint(equalTo: scrollView.contentLayoutGuide.rightAnchor, constant: 0).isActive = true 添加已排列的子视图,则实际上只应添加大小限制,因为定位将由UIStackViewaxisalignment的组合决定,和distribution。相反,对于spacing的约束,当您固定四条边时,您不需要添加大小限制,因为这将由引脚约束决定。

另外,请注意控制台记录布局错误。如果您有,可以尝试wtf autolayout使其更具可读性。

答案 1 :(得分:0)

发生这种情况是因为我将imageStack添加到垂直stackView两次:

{{1}}

最后我删除了最后一行,现在滚动工作正常

感谢大家的帮助!