【问题标题】:Create constraints between two subviews programmatically以编程方式在两个子视图之间创建约束
【发布时间】:2018-01-16 10:50:39
【问题描述】:

我在一个滚动视图内有一个内容视图以及其他一些视图,滚动视图的高度会根据内容视图的高度而变化,而内容视图的高度由其子视图的高度决定。

我正在以编程方式向 contentview 添加两个子视图。

childView1 = CustomView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 200))

childView2 = CustomView(frame: CGRect(x: 0, y: 210, width: self.view.frame.width, height: 200))

contentView.addSubview(childView1)
contentView.addSubview(childView2)

// childView1 top should be equal to contentView top           
let topConstraint = NSLayoutConstraint(item: childView1, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .top, multiplier: 1, constant: 0)

// childView2 bottom should be equal to contentView bottom                       
let bottomConstraint = NSLayoutConstraint(item: childView2, attribute: .bottom, relatedBy: .equal, toItem: contentView, attribute: .bottom, multiplier: 1, constant: 0)

// childView1 leading should be equal to contentView leading 

let leadingConstraint1 = NSLayoutConstraint(item: childView1, attribute: .leading, relatedBy: .equal, toItem: contentView, attribute: .leading, multiplier: 1, constant: 0)

// childView1 trailing should be equal to contentView trailing  

let trailingConstraint1 = NSLayoutConstraint(item: contentView1, attribute: .trailing, relatedBy: .equal, toItem: contentView, attribute: .trailing, multiplier: 1, constant: 0)

// childView2 leading should be equal to contentView leading                       

let leadingConstraint2 = NSLayoutConstraint(item: childView2, attribute: .leading, relatedBy: .equal, toItem: contentView, attribute: .leading, multiplier: 1, constant: 0)

// childView2 trailing should be equal to contentView trailing  

let trailingConstraint2 = NSLayoutConstraint(item: childView2, attribute: .trailing, relatedBy: .equal, toItem: contentView, attribute: .trailing, multiplier: 1, constant: 0)

// Vertical Space between two child views is 10             
let constraintTwoSubViews = NSLayoutConstraint(item: childView1, attribute: .bottom, relatedBy: .equal, toItem: childView2, attribute: .top, multiplier: 1, constant: 10)


contentView.addConstraints([topConstraint , bottomConstraint , leadingConstraint1,trailingConstraint1 , leadingConstraint2 , trailingConstraint2 , constraintTwoSubViews])

问题是 contentView 的高度没有按照子视图增长。 因此,我的滚动浏览量没有增长。

  1. 当我添加第二个子视图时,我不想指定 y = 210 ,我希望它的位置通过空间约束来计算 两个子视图,有可能吗?

  2. 如何使内容视图高度根据其子视图增加?

【问题讨论】:

  • 确保将 translatesAutoresizingMaskIntoConstraints 设置为 false 对于 childView1childView2,例如:childView1.translatesAutoresizingMaskIntoConstraints = false

标签: ios swift uiscrollview autolayout


【解决方案1】:

当我需要可滚动视图时我会做什么:

  1. 我将scrollView 添加到层次结构并使用自动布局来正确布局它,例如,如果它应该覆盖viewController 的整个view

    scrollView.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        scrollView.leftAnchor.constraint(equalTo: self.view.leftAnchor),
        scrollView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
        scrollView.topAnchor.constraint(equalTo: self.view.topAnchor),
        scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
    ])
    
  2. 然后您需要在scrollView 中添加一个contentView 并为其提供适当的布局约束,因此如果您想要在我上面开始的示例中垂直滚动scrollView,您需要以下自动布局约束:

    contentView.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        // horizontal anchors of contentView are constrained to scrollView superview
        // to prevent it from scrolling horizontally
        contentView.leftAnchor.constraint(equalTo: self.view.leftAnchor),
        contentView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
        // but vertical anchors of contentView are constrained to
        // scrollView to allow scrolling
        contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
        contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
    ])
    

    请注意,我将contentViewleftAnchorrightAnchor 限制为self.view 而不是scrollView,以使其具有固定宽度。但是,顶部和底部锚点被限制在滚动视图中,因此当contentView 需要更多空间时,它们会展开和滚动。

  3. 现在您将所需的所有内容添加到 contentView,并使用自动布局对其进行布局,就好像 contentView 是一个无限高的视图 - scrollView 将通过滚动来处理整个呈现.在您的情况下,我认为您可以使用UIStackView 来布置这两个视图。但是,CustomView 的帧将使用自动布局计算,所以我认为您不能依赖直接设置帧 - 因此我也使用约束来设置它们的高度(宽度将被 stackView 拉伸):

    let stack = UIStackView()
    stack.spacing = 10
    stack.distribution = .fill
    stack.alignment = .fill
    stack.axis = .vertical
    
    contentView.addSubview(stack)
    stack.addArrangedSubview(childView1)
    stack.addArrangedSubview(childView2)
    
    childView1.translatesAutoresizingMasks = false
    childView2.translatesAutoresizingMasks = false
    
    NSLayoutConstraint.activate([
        contentView.topAnchor.constraint(equalTo: stack.topAnchor),
        contentView.leadingAnchor.constraint(equalTo: stack.leadingAnchor),
        contentView.trailingAnchor.constraint(equalTo: stack.trailingAnchor),
        contentView.bottomAnchor.constraint(equalTo: stack.bottomAnchor),
    
        // setting their heights using constraints
        childView1.heightAnchor.constraint(equalToConstant: 200),
        childView2.heightAnchor.constraint(equalToConstant: 200),
        ])
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    相关资源
    最近更新 更多