0

I am trying to build a stack view with UIStackView that always shows 3 views at max, but can also show none, 1 or 2 views at the same time.

The whole stack view is supposed to be dynamic. At the beginning the stack view is empty. Another function will add a new view at the top with stackView.insertArrangedSubview(at: 0). If another view is added, then the previous view at index 0 should be pushed to index 1. That's why I picked the UIStackView, since it takes care of the reordering of existent views.

When a third view is pushed in, the other two will move down a slot again. Now, in case a fourth view get pushed in, all previous three views will move down again, but the fourth will then be removed from the stack view.

Here comes a small extra condition though:

The view at the first index should always be double the size of the remaining 2 views. So first view should be 50% of the whole stack view. Views at index 1 and 2 should therefore be 25% in height.

If a new view is pushed in, the currently at index 0 view will therefore have to shrink, move down to the middle, and be moved to index 1 of the stack view.

The idea is similar to how Growl Notification System work.

This image shows the basic layout of how the views should look.

SO the question now is, are UIStackViews the correct way to tackle this issue or would be working with constraints only (e.g. with SnapKit) be a better way? Even with UIStackView I would probably need to have a lot of constraints to fulfil the requirements.

So maybe I should just have an addNewView function that updates all constraints and call layoutIfNeeded in a UIView.animate block to have the transition of a view pushing down the others and the last view getting pushed out?

What do you guys think? If there exists a framework that already does something similar, I would appreciate pointers as well.

  • I hope that [Q&A](https://stackoverflow.com/questions/40254889/uistackview-distribution-fill-equally/40256540#40256540) might be helpful to you as a start point... – Ahmad F Mar 19 '17 at 15:09
  • Anything this dynamic will probably require both constraints and UIStackviews. You can add width constraints to views before adding them to the stack view and the stack view will respect those constraints. But this is a very broad question - you just need to write the code and make it work. – Robotic Cat Mar 19 '17 at 15:25

1 Answers1

0

Here is one option. You'll need a little code to manage adding / removing views, but that shouldn't be difficult. Notes follow the image:

enter image description here

Start with placing View A, View B and View C onto the main view. Don't worry about sizing or positioning, and don't give them any constraints... the StackView will handle all of that.

Select B and C and embed them in a Vertical StackView. Alignment: Fill, Distribution: Fill Equally, and Spacing: 8

Next, select A and the just-created-StackView, and embed them into a Vertical StackView. Also setup this StackView with Alignment: Fill, Distribution: Fill Equally, and Spacing: 8

Now, select this newly create StackView - the "top most" StackView - and give it constraints as desired... here I set Leading, Top, Trailing and Bottom all equal to 16.

Now, you just need code along the lines of:

func addView(newView: UIView) -> Void {

    // if ViewC has a subview, remove its subview
    // if ViewB has a subview, move ViewB's subview to ViewC
    // if ViewA has a subview, move ViewA's subview to ViewB
    // add newView as a subview of ViewA

}

Ugh... trying to be really clear on this... Views A, B and C will always exist as you see them here (with clear backgrounds, so you don't really see them). When you add / remove / move "new" views, you add them as subviews of A, B and C. Make sense?

DonMag
  • 69,424
  • 5
  • 50
  • 86