rraallvv
rraallvv

Reputation: 2943

How to remove reappearing padding in NavigationBar for Xamarin.Forms on iOS?

I'm using the snippet of code in this answer to remove the spacing between icons, and it seems to remove also the padding to the right in the NavigationBar. The problem is that after screen orientation changes of after I push or pop pages in and out of the navigation stack the padding to the right reappears.

Why is this padding removed the first time the custom renderer adds the custom views?

Is there a way to remove the padding altogether?

enter image description here

enter image description here

Update

Removing the constraints with negative constants, as suggested in the answer below, seems to work at first but those are put back at some point.

enter image description here

Upvotes: 1

Views: 829

Answers (1)

Ax1le
Ax1le

Reputation: 6641

The way to remove the padding is difference between iOS7+ and iOS11.

On iOS7+:

We can remove it by adding a UIBarButtonSystemItem.FixedSpace like:

public override void ViewWillAppear(bool animated)
{
    base.ViewWillAppear(animated);

    var navigationItem = this.NavigationController.TopViewController.NavigationItem;

    List<UIBarButtonItem> list = new List<UIBarButtonItem>();
    foreach (var rightItem in navigationItem.RightBarButtonItems)
    {
        var button = new UIButton(new CGRect(0, 0, 32, 32));
        button.SetImage(rightItem.Image, UIControlState.Normal);

        FieldInfo fi = rightItem.GetType().GetField("clicked", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy);
        Delegate del = (Delegate)fi.GetValue(rightItem);
        button.TouchUpInside += (EventHandler)del;

        UIBarButtonItem item = new UIBarButtonItem(button);
        list.Add(item);
    }

    if (!UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
    {
        UIBarButtonItem negativeSpacer = new UIBarButtonItem(UIBarButtonSystemItem.FixedSpace);
        negativeSpacer.Width = -16;
        list.Insert(0, negativeSpacer);
    }

    this.NavigationController.TopViewController.NavigationItem.RightBarButtonItems = list.ToArray();
}

On iOS 11:

The navigationBar on iOS11 has some difference, so we could achieve this by modifying something in the method ViewDidLayoutSubviews() and ViewWillAppear():

public override void ViewDidLayoutSubviews()
{
    base.ViewDidLayoutSubviews();

    tryToRelayout();
}

public override void ViewWillAppear(bool animated)
{
    base.ViewWillAppear(animated);
    ... ...//code above

    tryToRelayout();
}

void tryToRelayout()
{
    if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
    {
        UINavigationItem item = NavigationController.TopViewController.NavigationItem;
        var array = item.RightBarButtonItems;
        if (array != null)
        {
            UIBarButtonItem buttonItem = array[0];
            if (buttonItem.CustomView.Superview != null)
            {
                UIView view = buttonItem.CustomView.Superview.Superview.Superview;
                var arrayConstraint = view.Constraints;
                foreach (NSLayoutConstraint constant in arrayConstraint)
                {
                    if (constant.Constant < 0)
                    {
                        constant.Constant = 0;
                    }
                }
            }
        }
    }
}

Upvotes: 1

Related Questions