GT Kim
GT Kim

Reputation: 339

Adding views dynamically to UIStackview

I'm trying to add views(or buttons) to UIStackView dynamically.

At first, the UIStackView has no arranged views (vertically), and after getting from some http response, several views(buttons) are added to UIStackView. UIStackView is also autolayout to hold a specific area. I've tried to find dynamic adding example, but failed.

Anyone can show me the examples of adding view onto UIStackView dynamically?

Upvotes: 6

Views: 15054

Answers (3)

ekscrypto
ekscrypto

Reputation: 3806

I use this code in one of my projects:

    let baseFrame = CGRect(origin: .zero, size: CGSize(width: requiredWidth, height: partitionHeight))
    for instrument in instruments {
        let partitionView = PartitionOnDemand(instrument: instrument, mode: playbackMode, frame: baseFrame, referenceView: partitionsAnimator)
        partitionsStackView.addArrangedSubview(partitionView)
        let tab = InstrumentInfoTabContainer.instantiate(with: instrument) {
            self.focus(on: instrument)
        }
        tabsStackView.addArrangedSubview(tab)
    }

Upvotes: 5

GT Kim
GT Kim

Reputation: 339

While trying with answers, I happend to find how to work it.

class ViewController: UIViewController {

@IBOutlet weak var stack: UIStackView!
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
@IBAction func onBtn_Create(_ sender: Any) {
    createButton("new button ...")
}
@IBAction func onBtn_Delete(_ sender: Any) {
    if let v = stack.arrangedSubviews.last {
        stack.removeArrangedSubview(v)
        v.removeFromSuperview()
    }

}


func createButton(_ title: String) {
    let button = UIButton()
    button.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
    button.backgroundColor = UIColor.blue
    button.setTitle(title, for: .normal)
    button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)

    stack.addArrangedSubview(button)
}


@objc func buttonAction(sender: UIButton!) {
    print("Button tapped")
}

}

And, I anchored to UIStackView, Trailing=0, Leading=0, Top=0, Bottom=8 to TextView.Top

The subviews inside it are intact without any constraints.

Thank you.enter image description here

Upvotes: -1

iamVishal16
iamVishal16

Reputation: 1780

It may help you. Please follow this points:

  • Add UIScrollView to your UIViewController in storyboard or XIB.
  • Initiate an NSMutableArray name it arrViews gets server response and adds view in the array.
  • Initialise UIStackViewpass arrView array in the init method.
  • After that UIStackView will be added subview of UIScrollView.
  • Add constraint programmatically to UIStackView. That's it.

    if let response = self.serverResponse {
        if let body = response.responseBody {
    
            if let view = body.views {
                arrViews =  createSubViews(view)
            }
    
        }
    }
    
    let stackView = UIStackView(arrangedSubviews: arrViews)
    stackView.translatesAutoresizingMaskIntoConstraints = false
    stackView.axis = .vertical
    stackView.spacing = 16
    stackView.distribution = .fill
    self.scrollView.addSubview(stackView)
    
    //constraints
    
    let leading = NSLayoutConstraint(item: stackView, attribute: .leading, relatedBy: .equal, toItem: self.scrollView, attribute: .leading, multiplier: 1.0, constant: 0)
    self.scrollView.addConstraint(leading)
    let trailing = NSLayoutConstraint(item: stackView, attribute: .trailing, relatedBy: .equal, toItem: self.scrollView, attribute: .trailing, multiplier: 1.0, constant: 0)
    self.scrollView.addConstraint(trailing)
    let top = NSLayoutConstraint(item: stackView, attribute: .top, relatedBy: .equal, toItem: self.scrollView, attribute: .top, multiplier: 1.0, constant: 0)
    self.scrollView.addConstraint(top)
    
    let bottom = NSLayoutConstraint(item: stackView, attribute: .bottom, relatedBy: .equal, toItem: self.scrollView, attribute: .bottom, multiplier: 1.0, constant: 0)
    self.scrollView.addConstraint(bottom)
    
    let equalWidth = NSLayoutConstraint(item: stackView, attribute: .width, relatedBy: .equal, toItem: self.scrollView, attribute: .width, multiplier: 1.0, constant: 0)
    
    self.scrollView.addConstraint(equalWidth)
    
    
    leading.isActive = true
    trailing.isActive = true
    top.isActive = true
    bottom.isActive = true
    equalWidth.isActive = true
    

Hope it will help you. Happy coding :)

Upvotes: 8

Related Questions