Adding views dynamically to UIStackview
Asked Answered
R

3

6

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?

Rolon answered 24/7, 2018 at 4:45 Comment(4)
not sure if that will work, I think I tried to do that once and it failedBeanstalk
What you have done so far?Bingen
Have you been able to solve your issue? If yes please select an answer from belowNernst
All answers are appreciated, but no exact answer for my need. Do I have to pick up one, tho?Rolon
S
8

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 :)

Supranational answered 24/7, 2018 at 5:19 Comment(2)
Thank you. good suggestion. I've not thought of that scrollview at all. I wil try that.Rolon
Welcome. If it will work for you let me know and please accept the answer and vote me up. ;) to help more.Supranational
N
5

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)
    }
Nernst answered 24/7, 2018 at 4:58 Comment(3)
Thank you! but I can't understand yours for my bad skill.Rolon
its a loop that fills in two stackviews with musical partitions and intrument infos. The important part is the addArrangedSubviewNernst
I was able to add views dynamically to StackView by using addArrangedSubview - thank you.Hautesalpes
R
-1

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

Rolon answered 24/7, 2018 at 7:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.