如何使用autoLayout创建包含水平和垂直分页的强大ScrollView?

时间:2017-08-08 01:53:45

标签: ios swift uiscrollview autolayout

情况

所以我试图创建一个UIScrollView,它基本上是一个菜单导航栏,用户可以通过在菜单项之间滑动来导航,其中有垂直布局的页面和水平放置的子页面出。样机:enter image description here

我这样做的方法是创建一个UIScrollView,其框架大小为UILabel,我将isPagingEnabled设置为true。然后我尝试添加UIStackView,每行指示一个页面,每行的内容是一个子页面。我将scrollView.contentSize设置为UIStackView的大小。问题是我的所有标签框架都是零,而UIScrollView不起作用。

:/

真的想避免得到帮助,因为我觉得我可以自己做这件事,但我已经花了两天时间而且我已经失去了所有的希望。

代码

以下是我添加标签的代码。它调用了scrollview的超级浏览量ini t(因为UIScrollView位于自定义UIView我调用crossNavigation View中。

private func addScrollViewLabels() {

    //Get Max Number of Items in a Single Row
    var maxRowCount = -1
    for item in items {
        if (item.contents.count > maxRowCount) {maxRowCount = item.contents.count}
    }

    self.rowsStackView.axis = .vertical
    self.rowsStackView.distribution = .fillEqually
    self.rowsStackView.alignment = .fill
    self.rowsStackView.translatesAutoresizingMaskIntoConstraints = false
    self.scrollView.addSubview(rowsStackView)

    for i in 0 ..< items.count {
        let row = items[i].contents
        let rowView = UIView()
        self.rowsStackView.addArrangedSubview(rowView)
        var rowLabels : [UILabel] = []
        //First Label
        rowLabels.append(UILabel())
        rowView.addSubview(rowLabels[0])

        NSLayoutConstraint(item: rowLabels[0], attribute: .leading, relatedBy: .equal, toItem: rowView, attribute: .leading, multiplier: 1.0, constant: 0.0).isActive = true
        NSLayoutConstraint(item: rowLabels[0], attribute: .top, relatedBy: .equal, toItem: rowView, attribute: .top, multiplier: 1.0, constant: 0.0).isActive = true
        NSLayoutConstraint(item: rowLabels[0], attribute: .bottom, relatedBy: .equal, toItem: rowView, attribute: .bottom, multiplier: 1.0, constant: 0.0).isActive = true
        NSLayoutConstraint(item: rowLabels[0], attribute: .width, relatedBy: .equal, toItem: containerView, attribute: .width, multiplier: 0.55, constant: 0.0).isActive = true
        //Middle Labels
        for j in 1 ..< row.count {
            rowLabels.append(UILabel())
            rowView.addSubview(rowLabels[j])

            //Stick it to it's left
            NSLayoutConstraint(item: rowLabels[j], attribute: .leading, relatedBy: .equal, toItem: rowLabels[j-1], attribute: .trailing, multiplier: 1.0, constant: 0.0).isActive = true
            //Stick top to rowView
            NSLayoutConstraint(item: rowLabels[j], attribute: .top, relatedBy: .equal, toItem: rowView, attribute: .top, multiplier: 1.0, constant: 0.0).isActive = true
            //Row Height is equal to rowView's Height
            NSLayoutConstraint(item: rowLabels[j], attribute: .height, relatedBy: .equal, toItem: rowView, attribute: .height, multiplier: 1.0, constant: 0.0).isActive = true
            //rowLabels[j].width = containerView.width * 0.55 (so other labels can peek around it)
            NSLayoutConstraint(item: rowLabels[j], attribute: .width, relatedBy: .equal, toItem: containerView, attribute: .width, multiplier: 0.55, constant: 0.0).isActive = true
        }

        //lastLabel.trailing = rowView.trailing
        NSLayoutConstraint(item: rowLabels[row.count-1], attribute: .trailing, relatedBy: .equal, toItem: rowView, attribute: .trailing, multiplier: 1.0, constant: 0.0).isActive = true
    }

    //Constraints for stack view:
    //rowsStackView.height = scrollView.height * items.count
    NSLayoutConstraint(item: rowsStackView, attribute: .height, relatedBy: .equal, toItem: scrollView, attribute: .height, multiplier: CGFloat(self.items.count), constant: 0.0).isActive = true
    //rowsStackView.height = scrollView.height * items.count
    NSLayoutConstraint(item: rowsStackView, attribute: .leading, relatedBy: .equal, toItem: containerView, attribute: .leading, multiplier: 1.0, constant: 0.0).isActive = true
    NSLayoutConstraint(item: rowsStackView, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .top, multiplier: 1.0, constant: 0.0).isActive = true
    NSLayoutConstraint(item: rowsStackView, attribute: .width, relatedBy: .equal, toItem: containerView, attribute: .width, multiplier: 1.0, constant: 0.0).isActive = true

    self.scrollView.contentSize = rowsStackView.frame.size
}

1 个答案:

答案 0 :(得分:1)

看看我根据你的模拟制作的这个demo project。 它为您想要做的一切设置了框架。

检查视图层次结构,您将了解在何处配置布局以使其完全符合您的要求。

最后一步是调整分页,以便获得所需的快照行为。有很多方法可以做到这一点,但它有点涉及。

祝你好运!

ScreenShot