android – iOS equivalent to View.GONE-ThrowExceptions

Exception or error:

Is there an iOS equivalent to the Android View.GONE?

In Android, setting a view to GONE will make it invisible and will ensure that the view does not take up any space in the layout. I know with iOS, you can set a view to hidden with

[viewName setHidden:true];

but the view still takes up space in the layout, and I think it would be inefficient to completely remove the view and recreate it later.

(note: I’ve seen this post: iOS equivalent for Android View.GONE visibility mode but there is no accepted answer, and setting the height to 0 did not work for me, as the subsequent views on the page did not shift after my view was removed)

How to solve:

Add the width/height constraints with constant = 0 to your View will make your View have width and height = 0 (like it GONE)

// set the height constraint to 0 
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:theGoneView
                                                                   attribute:NSLayoutAttributeHeight
                                                                   relatedBy:NSLayoutRelationEqual
                                                                      toItem:nil
                                                                   attribute:NSLayoutAttributeNotAnAttribute
                                                                  multiplier:1.0
                                                                    constant:0]];

// set the width constraint to 0            
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:theGoneView
                                                               attribute:NSLayoutAttributeWidth
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:nil
                                                               attribute:NSLayoutAttributeNotAnAttribute
                                                              multiplier:1.0
                                                                constant:0]];

In Swift

// set the width constraint to 0
let widthConstraint = NSLayoutConstraint(item: theGoneView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 0)
view.addConstraint(widthConstraint)

// set the height constraint to 0        
let heightConstraint = NSLayoutConstraint(item: theGoneView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 0)
    view.addConstraint(heightConstraint)

Or this UIView extension

extension UIView {        

    func goAway() {
        // set the width constraint to 0
        let widthConstraint = NSLayoutConstraint(item: self, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 0)
        superview!.addConstraint(widthConstraint)

        // set the height constraint to 0
        let heightConstraint = NSLayoutConstraint(item: self, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 0)
        superview!.addConstraint(heightConstraint)
    }

}

Hope this help

###

Only possible equivalent can be AFAIK:

[yourView removeFromSuperview]

Until you remove view from its superview in ios it will take space in the layout.

So depending on your need, you can add or remove view when required (same as view.GONE in android).

###

I’m currently making the transition between Android and iOS using Swift and that was one of my first problems. After searching on the Internet I found that some people had good results by setting the height or width of the UIView to 0, depending on whether you want the view to disappear vertically or horizontally. To implement this idea in my app I defined two functions like so:

enum Direction {
    case HORIZONTAL, VERTICAL
}

func removeView(view: UIView, direction: Direction) {
    // Removing the view vertically
    if direction == .VERTICAL {
        let constraint = NSLayoutConstraint(item: view as UIView,
                                            attribute: NSLayoutAttribute.Height,
                                            relatedBy: .Equal,
                                            toItem: nil,
                                            attribute: NSLayoutAttribute.NotAnAttribute,
                                            multiplier: 0,
                                            constant: 0)
        view.addConstraint(constraint)
    } else { // Removing the view horizontally
        let constraint = NSLayoutConstraint(item: view as UIView,
                                            attribute: NSLayoutAttribute.Width,
                                            relatedBy: .Equal,
                                            toItem: nil,
                                            attribute: NSLayoutAttribute.NotAnAttribute,
                                            multiplier: 0,
                                            constant: 0)
        view.addConstraint(constraint)
    }
}

// Removing the view both horizontally and vertically
func removeView(view: UIView) {
    let constraintH = NSLayoutConstraint(item: view as UIView,
                                            attribute: NSLayoutAttribute.Height,
                                            relatedBy: .Equal,
                                            toItem: nil,
                                            attribute: NSLayoutAttribute.NotAnAttribute,
                                            multiplier: 0,
                                            constant: 0)
    let constraintW = NSLayoutConstraint(item: view as UIView,
                                            attribute: NSLayoutAttribute.Width,
                                            relatedBy: .Equal,
                                            toItem: nil,
                                            attribute: NSLayoutAttribute.NotAnAttribute,
                                            multiplier: 0,
                                            constant: 0)
    view.addConstraint(constraintH)
    view.addConstraint(constraintW)
}

And it seems to work on the simulator. Hope this helps.

###

The cleanest solution to me is to embed the components you want to “be moving” in a UIStackView (iOS 9.0+), then, by setting UIView.isHidden = true on the desired UIView, you achieve exactly the View.GONE effect because UIStackView wraps content and is automatically reacting to changes in size of its subviews.

Leave a Reply

Your email address will not be published. Required fields are marked *