iOS equivalent for Android View.GONE visibility mode

IphoneIosInterface BuilderVisibilityAutolayout

Iphone Problem Overview


I'm developing an app for iOS and I'm using the Storyboard with AutoLayout ON. One of my view controllers has a set of 4 buttons, and in certain circumstances i would like to make the first one disappear.

If I use the setHidden:TRUE method the UIButton become invisible but it still obviously take space in the view, and the result is an "hole" which I've not been able to fill making the remaining UIButton to float towards the top of the main view.

In Android I would have simply used View.GONE instead of View.INVISIBLE, but in iOS I'm stuck with this behaviour and I don't want to believe that the only solution is to manually (yes I mean programmatically) move the remaining elements to the top.

I thought I would have been able to do it setting some sort of Constraint to make everything as automatic as it is in Android but I've had no luck.

Before I turn Autolayout OFF, can someone point me to the right direction?

I'm using the IB, but I'm comfortable with programmatic stuff as well.

UPDATE:

Setting the component height to 0 doesn't help as well.

I tried something like this:

UIButton *b;
CGRect frameRect = b.frame;
frameRect.size.height = 0;
b.frame = frameRect;

Iphone Solutions


Solution 1 - Iphone

Adding a constraint(NSLayoutAttributeHeight) that sets height of the view to 0 worked for me:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.captchaView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:0]];

Solution 2 - Iphone

All of answers on this questions are inefficient. Best way to equvailent of Android setVisibility:Gone method on iOS is that StackView first select components then in editor, embed in, Stack View,

connect new stack view with IBOutlet, then:

hidden:

UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0];
        firstView.hidden = YES;

visibility:

UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0];
        firstView.hidden = NO;

as using stack view, all constraints will be keeped!

Document

Solution 3 - Iphone

add a height constraint to your view as follows:enter image description here

then make an outlet for the height constraint in your viewController file as follows:enter image description here

& then in your viewDidLoad method change constraint height to 0 as follows:

override func viewDidLoad() {
    super.viewDidLoad()
nsLcButtonHeight.constant = 0
}

Solution 4 - Iphone

To achieve Androids.GONE functionality on iOS is to use a UIStackView. After that hide the child by position. (Apples documentation)

SWIFT 4:

let firstView = cell.rootStackView.arrangedSubviews[0]
    firstView.isHidden = true // first view gone

It's a table cell example, just put both insides Stack view and get item for GONE the child.

enter image description here

Solution 5 - Iphone

What you can do is to group your views under a stack view. Then when you hide a particular view, the remaining views will be shifted automatically to fill the space.

You may want to check out the Apple Documentation on Stack Views: https://developer.apple.com/reference/uikit/uistackview

or online tutorials such as: https://www.appcoda.com/stack-views-intro/

Solution 6 - Iphone

  1. If your buttons are placed vertically then you must set the height to 0 and in case of horizontally placed buttons, try setting width to 0 or you can set both to 0.

OR

  1. you could try this approach which sets button2 on top of button1:

    • (void)viewDidLoad { [super viewDidLoad];

    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button1 setTitle:@"hello" forState:UIControlStateNormal];

    UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button2 setTitle:@"world" forState:UIControlStateNormal];

    [button1 sizeToFit]; [button2 sizeToFit]; [button2 setFrame:CGRectMake(button1.frame.origin.x, button1.frame.origin.y, button2.frame.size.width, button2.frame.size.height)];

    [self.view addSubview:button1]; [self.view addSubview:button2];

    }

Solution 7 - Iphone

Solution 8 - Iphone

This question is pretty old but the closet thing I've found is setting additional constraints (so the views around the "gone" view know what to do once it's missing)

A  which you want to be     A
|  after setting B to gone  |
B 	                        C
|                               
C                               
  1. Set a lower priority (750) constraint from C to A.

  2. Add B's top and bottom constraints (or left and right if you want your view to collapse horizontally) to an NSLayoutConstraint array bConstraints. Do this by:

  3. Control click and drag from the constraint to the ViewController

  4. Change Connection from Outlet to Outlet Collection

  5. For name put bConstraints.

  6. Hit connect. This will create an @IBOutlet var bConstraints: [NSLayoutConstraint]! in your ViewController

  7. To add additional constraints: drag from the constraint in Storyboard to the @IBOutlet variable name

  8. Then hide B

     B.hidden = true
     NSLayoutConstraint.deactivateConstraints(bConstraints)
    
  9. To unhide

     B.hidden = false
     NSLayoutConstraint.activateConstraints(bConstraints)
    

Obviously the more and more views you have the more complex this grows, as you need additional constraints from each view

Solution 9 - Iphone

As my research has shown, not even AutoLayout can help you. You have to manually replace the views affected by the optionally shown component (in my case, all the views to the bottom of the optional view, but you I am sure you can adapt this to handle all the buttons to the right of your optional button):

- (IBAction)toggleOptionalView:(id)sender {
    if (!_expanded) {
        self.optionalView.frame = CGRectMake(self.optionalView.frame.origin.x, self.optionalView.frame.origin.y, self.optionalView.frame.size.width, _optionalHeight);
        self.bottomView.frame = CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y+_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height);
        _expanded = YES;
    } else {
        self.optionalView.frame = CGRectMake(self.optionalView.frame.origin.x, self.optionalView.frame.origin.y, self.optionalView.frame.size.width, 0);
        self.bottomView.frame = CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y-_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height);
        _expanded = NO;
    
    }
}

It is advisable not to hard-code the height/width of the optional components, otherwise your code breaks every time you edit the XIB/Storyboard. I have a field float _optionalHeight which I set in viewDidLoad, so it is always up to date.

Solution 10 - Iphone

You can also clear the page, or at least certain cells of the page, and redefine the whole thing. It's fast and works well. I didn't write the code but found it in this pre-existing project I'm working on. Create ManagementTableSection and ManagementTableCell classes to manage it all. Sorry I can't provide better defined code.

Solution 11 - Iphone

Building off the answer provided by Deniz, here is a solution using constraints in Swift

For example: If you have 3 views, A_view B_view and C_view vertically aligned in that order and you want to "Hide" B and also adjust the difference, add a constraint

B_view.removeFromSuperView()
var constr = NSLayoutConstraint(item: C_view, 
                                attribute: NSLayoutAttribute.Top, 
                                relatedBy: NSLayoutRelation.Equal, 
                                toItem: A_view, 
                                attribute: NSLayoutAttribute.Bottom,
                                multiplier: 1,
                                constant: 20)
view.addConstraint(constr)

constant is (in this case) the amount of vertical space between C_view and A_view

Solution 12 - Iphone

I added a new property to a custom UIView implementation called "visible" which, when set to false, adds a constraint to collapse the view (I only added a width constraint since my list is horizontal, but the best way might be to add a height constraint of 0 as well).

var visible:Bool = true{
        didSet{
            if(visible){
                clipsToBounds = false;
                removeConstraint(hideConstraint!)
            }else{
                clipsToBounds = true
                addConstraint(hideConstraint!)
            }
        }
    }

You need to initialize the zero-width constraint on the view and add it as a field:

private var hideConstraint:NSLayoutConstraint?


func someInitFunction(){
    hideConstraint = NSLayoutConstraint(item: self, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 0.0)
    ...
}

Solution 13 - Iphone

setHidden:TRUE/FALSE is the nearest equivalent to Android View.GONE/VISIBLE.

The View not necessarily take space if not visible!

I have made a ComboBox-Alike with a ListView laying on top of other views. I's only visible while selecting:

enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionelbuildView Question on Stackoverflow
Solution 1 - IphoneDenizView Answer on Stackoverflow
Solution 2 - IphoneUcdemirView Answer on Stackoverflow
Solution 3 - IphoneAjinkya PatilView Answer on Stackoverflow
Solution 4 - IphoneMd Imran ChoudhuryView Answer on Stackoverflow
Solution 5 - IphonemechdonView Answer on Stackoverflow
Solution 6 - IphoneiphondroidView Answer on Stackoverflow
Solution 7 - Iphonepoyo fever.View Answer on Stackoverflow
Solution 8 - IphonewyuView Answer on Stackoverflow
Solution 9 - IphoneKatluView Answer on Stackoverflow
Solution 10 - IphonecranedView Answer on Stackoverflow
Solution 11 - IphoneThe4thIcemanView Answer on Stackoverflow
Solution 12 - IphoneAnthony De SmetView Answer on Stackoverflow
Solution 13 - IphonethpitschView Answer on Stackoverflow