1

I have a viewcontroller that holds multiple stackviews. There is a button that when pressed, the corresponding uiview wil become fullscreen inside the original view. There is a different button that is supposed to make the uiview go back to its original stackview. The uiview itself contains other views. I am having some problems doing that. The uiview does end up in the stackview, but not near the same size/place it used to be. I am not sure how to solve this, and been going at it for several hours now, looking at multiple sources.

This is the code that makes the uiview go fullscreen:

private func moveToFrontOfCardView(v: UIView) {
    originalView = v.superview

    if let stack = originalView as? UIStackView {
        stack.removeArrangedSubview(v)
    }
    myCardView.addSubview(v)

    let topConstraint = NSLayoutConstraint(item: v, attribute: .top, relatedBy: .equal, toItem: myCardView, attribute: .top, multiplier: 1, constant: 10)
    let bottomConstraint = NSLayoutConstraint(item: v, attribute: .bottom, relatedBy: .equal, toItem: myCardView, attribute: .bottom, multiplier: 1, constant: -10)
    let leftConstraint = NSLayoutConstraint(item: v, attribute: .left, relatedBy: .equal, toItem: myCardView, attribute: .left, multiplier: 1, constant: 10)
    let rightConstraint = NSLayoutConstraint(item: v, attribute: .right, relatedBy: .equal, toItem: myCardView, attribute: .right, multiplier: 1, constant: -10)

    myCardView.addConstraints([topConstraint, bottomConstraint, leftConstraint, rightConstraint])
}

Original size

And this is the code I use when I want it to go back:

private func moveToOriginalPosition(v: UIView) {
    if let stack = originalView as? UIStackView {
        stack.addArrangedSubview(v)
    }
}

enter image description here

Does anyone have a clue how I could fix this?

EDIT I've tried Saqib and Bilals answer, but I get this as a result:

enter image description here

Jer
  • 37
  • 6

3 Answers3

2

Declare a class variable for tracking view's index

var selectedIndex = 0 // Contains Current Seleceted view's index

overrie func viewDidLoad() { ...
  • Before removing view from stackview get the view index like this selectedIndex = stack.subviews.index(of: v)

  • keep reference to all the constraints.

  • Before adding it back disable all the constraints topConstraint.isActive = false

  • Now add the view at the same index using stack.insertArrangedSubview(view, at: selectedIndex)

An other option is to create a same new view and just hide/unhide the one in stackview. StackView automatically fills the space accordingly for the hidden views.

Saqib Omer
  • 5,387
  • 7
  • 50
  • 71
Bilal
  • 18,478
  • 8
  • 57
  • 72
  • I've tried something similiar before, but no luck. I've tried it exactly as you suggested it and I get the result in the edit above – Jer Apr 24 '18 at 10:44
1

By the looks of things you don't need to remove the original view. You could make a copy of it then display the copy full screen. Then when you dismiss this copy you release the reference to it

  • I thought about it, but I am not sure that is better. The uiview itself has subviews. – Jer Apr 24 '18 at 10:32
  • Could you instead display a modal with the relavant information? – Rhys Kentish Apr 24 '18 at 10:33
  • I am not sure what you are asking. Could you explain? – Jer Apr 24 '18 at 11:24
  • Rather than displaying the view on the same screen have a modale pop up displaying the view? Is that the effect you want? – Rhys Kentish Apr 24 '18 at 11:32
  • 1
    No, it wasn't what I wanted. I want the user to have the feeling he/she stays in one screen as much as he/she can. A popover negates that a little bit. Popover was the easy way to get a similar result and would have been my go to process if it hadn't worked out what I was trying to achieve. But it did work out :-) Thank you for your suggestions! – Jer Apr 24 '18 at 20:15
1

You should deActivate the constraints you added to view when removed it from stackView, at the time you want add the view to the stackView again. For this you should make the constraints instance of your viewController class and next, write your moveToOriginalPosition(v: UIView) method like this:

    private func moveToOriginalPosition(v: UIView) {
        if let stack = originalView as? UIStackView {
        stack.addArrangedSubview(v)
        topConstraint.isActive = false
        bottomConstraint.isActive = false
        leftConstraint.isActive = false
        rightConstraint.isActive = false

        }
   }

Ofcourse, you should remove, these lines of codes from moveToFrontOfCardView(v: UIView) method:

    self.topConstraint = NSLayoutConstraint(item: v, attribute: .top, relatedBy: .equal, toItem: myCardView, attribute: .top, multiplier: 1, constant: 10)
    self.bottomConstraint = NSLayoutConstraint(item: v, attribute: .bottom, relatedBy: .equal, toItem: myCardView, attribute: .bottom, multiplier: 1, constant: -10)
    self.leftConstraint = NSLayoutConstraint(item: v, attribute: .left, relatedBy: .equal, toItem: myCardView, attribute: .left, multiplier: 1, constant: 10)
    self.rightConstraint = NSLayoutConstraint(item: v, attribute: .right, relatedBy: .equal, toItem: myCardView, attribute: .right, multiplier: 1, constant: -10)

    myCardView.addConstraints([topConstraint, bottomConstraint, leftConstraint, rightConstraint])

and add them where you make your view initialized. and replace below lines with above lines in moveToFrontOfCardView(v: UIView) method:

        topConstraint.isActive = true
        bottomConstraint.isActive = true
        leftConstraint.isActive = true
        rightConstraint.isActive = true
  • That's it! Thank you I did not realize it was those specific constraints that I needed to deactivate. I tried so many other things with the constraints, but it (in hindsight) it's so obvious. Thank you. It works exactly as I want it now. – Jer Apr 24 '18 at 11:48