2

I am super new iOS development and StackViews in general and need help calculating dynamic height in instances where a stack view will not be shown. There are cases where certain elements will not be shown depending on what I get back from the server.

However, when I call removeArrangedSubview the element is removed but the height isn't adjusted dynamically. How can I fix this?

I would like to avoid the Interface Builder all together and just do this programmatically. I have been using layout anchors for constraints.

Here's my code. You can put in a playground to see it.

    //: Playground - noun: a place where people can play


import UIKit
import Foundation

let view = UIView(frame: CGRect(x: 0, y: 0, width: 800, height: 140))

let firstStackView = UIStackView(frame: CGRectZero)
//firstStackView.heightAnchor.constraintGreaterThanOrEqualToConstant(40).active = true
firstStackView.axis = .Vertical
firstStackView.alignment = .Fill
firstStackView.distribution = .EqualSpacing

let titleStackView = UIStackView(frame: CGRectZero)
titleStackView.axis = .Horizontal
titleStackView.alignment = .Fill
titleStackView.distribution = .Fill
titleStackView.spacing = 3
firstStackView.addArrangedSubview(titleStackView)

let productStackView = UIStackView(frame: .zero)
productStackView.axis = .Horizontal
productStackView.alignment = .Leading
productStackView.distribution = .Fill
productStackView.spacing = 3
firstStackView.addArrangedSubview(productStackView)
//firstStackView.removeArrangedSubview(productStackView)

let secondStackView = UIStackView(frame: CGRectZero)
//secondStackView.heightAnchor.constraintEqualToConstant(30).active = true
secondStackView.axis = .Horizontal
secondStackView.distribution = .EqualSpacing


let title = UILabel(frame: CGRectZero)
title.text = "test1"
title.textColor = .blackColor()
//labelOne.backgroundColor = .blueColor()
let size = title.sizeThatFits(CGSizeZero)
print("\(size)")
title.widthAnchor.constraintEqualToConstant(size.width).active = true
//labelOne.heightAnchor.constraintEqualToConstant(30).active = true
titleStackView.addArrangedSubview(title)


let assigneeLabel = UILabel(frame: CGRectZero)
assigneeLabel.text = "test2"
assigneeLabel.textColor = .blackColor()
//labelTest.backgroundColor = .redColor()
assigneeLabel.textAlignment = .Left
//labelTest.heightAnchor.constraintEqualToConstant(30).active = true
titleStackView.addArrangedSubview(assigneeLabel)

let actions = UIButton(type: .Custom)
//buttonOne.backgroundColor = .redColor()
actions.setTitle("some button", forState: .Normal)
actions.setTitleColor(.blackColor(), forState: .Normal)
titleStackView.addArrangedSubview(actions)


let productOne = UILabel(frame: CGRectZero)
productOne.text = "something1"
productOne.numberOfLines = 0
let productLabelSize = productOne.sizeThatFits(CGSizeZero)
productOne.widthAnchor.constraintEqualToConstant(productLabelSize.width).active = true
productOne.textColor = .blackColor()
//labelTwo.backgroundColor = .blueColor()
productStackView.removeArrangedSubview(productOne)
//productStackView.addArrangedSubview(productOne)


let productTwo = UILabel(frame: CGRectZero)
productTwo.text = "something2"
productTwo.numberOfLines = 0
//productTwo.heightAnchor.constraintEqualToConstant(30).active = true
productTwo.textColor = .blackColor()
//labelTwo.backgroundColor = .blueColor()
productStackView.removeArrangedSubview(productTwo)
//productStackView.addArrangedSubview(productTwo)


let labelThree = UILabel(frame: CGRectZero)
labelThree.text = "sometime"
//labelThree.heightAnchor.constraintEqualToConstant(30).active = true
labelThree.textColor = .blackColor()
//labelThree.backgroundColor = .blueColor()
firstStackView.addArrangedSubview(labelThree)


let descriptionView = UILabel(frame: CGRectZero)
descriptionView.text = "some description about something"
descriptionView.textColor = .blackColor()
//descriptionView.backgroundColor = .redColor()
secondStackView.addArrangedSubview(descriptionView)

let tagsView = UILabel(frame: CGRectZero)
tagsView.text = "some more things"
tagsView.textColor = .blackColor()
secondStackView.addArrangedSubview(tagsView)
secondStackView.trailingAnchor.constraintEqualToAnchor(tagsView.trailingAnchor).active = true


let stackView = UIStackView(arrangedSubviews: [firstStackView, secondStackView])
stackView.layoutMargins = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
stackView.layoutMarginsRelativeArrangement = true
stackView.axis = .Vertical
stackView.frame = view.bounds
stackView.distribution = .FillProportionally

view.addSubview(stackView)

Before element is removed:enter image description here

After element is removed:enter image description here

I would like that gap to be gone and the height adjusted dynamically.

4

1 回答 1

0

如果您使用自动布局,则可以为视图的高度添加约束。

因此,对于初始设置,您可以执行以下操作:

class YourClass : UIViewController() {

   var heightConstraint = NSLayoutConstraint()

   func someMethod () {

    // load your View
    // get the height of view. 
    heightConstraint = yourView.heightAnchor.constraintEqualToConstant(height)
    self.view.addConstraint(heightConstraint)

   } 

   func deleteMemberStackView() {

     /// After deleting the member, get the new height of the view and do this
     self.view.removeConstraint(heightConstraint)
heightConstraint =  yourView.heightAnchor.constraintEqualToConstant(height)
     self.view.addConstraint(heightConstraint)

     UIView.animateViewDuration(0.3, completion: {
          self.view.layoutIfNeeded()
     })
   }

}
于 2016-07-06T06:12:23.293 回答