Search code examples
iosuibuttonxamarinvisibilitymvvmcross

Xamarin iOS UIButton hide/show


I have a Problem with my UIButton in my Xamarin-iOS project. I am workign with the great MvvmCross and the FluentLyout-Helpers (see: FluentLyout). But the layout is not my problem.

I set the Hidden-Property of my UIButton to true. So the button is no longer visible on my view. But the space for the button is still there.

In the following picture, you can see my problem. Between the google+ and the yammer button is a Twitter button (Hidden). But the Space is still there.

hidden problem

My layout-code:

// Set layout-constraints
View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

View.AddConstraints(
    View.VerticalStackPanelConstraints(new Margins(10),
    txtLabel, fbButton, msButton, goButton, twButton, yaButton));

Every button is created the same way:

var btn = UIButton.FromType(UIButtonType.System);
btn.SetTitle("title", UIControlState.Normal);
btn.Hidden = true;
Add(btn);

How can i avoid this? Any help would be great. Thanks


Solution

  • As you have already noticed, hidden views are still there.

    A solution I've found to work is to define constraints between the elements with surrounding the element that needs to be hidden, but with a lower priority.

    Then you can use RemoveFromSuperview () to remove a view from the layout. The constraints that use the removed view will break, and the additional constraints you made will take over.

    [edit]

    Alternatively you could make your buttons part of a tableview (and create them in a tablesource), then you could just remove individual buttons from the tablesource and ask the tableview to update.

    [edit2]

    Explaining the first suggestion in more detail:

    Let's assume we have 4 views inside a viewgroup: | A B C D |. I'm assuming horizontal direction here because that's easier for writing the post, but you can easily transpose it to vertical. The principle is the same.

    Normally we would just define 5 constraints to positions them in the horizontal direction.

    | to A
    A to B
    B to C
    C to D
    D to |
    

    Now if we remove B using RemoveFromSuperview(), we will also break the constraints that use B. The result is a broken layout.

    So let's give the previous five constraints a priority of 1000. And specify some more.

    | to B
    A to C
    B to D
    C to |
    

    And let's give them a lower priority of 900. Now when I call RemoveFromSuperview() on B the following will happen:

    A to B is broken
    B to C is broken
    A to C takes over
    

    And if I want I can also call RemoveFromSuperview() on D:

    C to D is broken
    D to | is broken
    C to | takes over
    

    If we want to be able to delete two consecutive views, we need to specify:

    | to C
    A to D
    B to |
    

    This method does have it's limits.

    For one, it doesn't really scale efficiently when confronted with 10's of view. Nor does it scale efficiently when you want to be able to remove 3 or even more views.

    But in simple cases it does work and for the other cases you can use TableView with TableSource.