Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override layoutSubviews to call [super layoutSubviews] and then find and reposition the button's view

I'm trying to reposition my UIBarButtonItem so that it sits with it's edges against the top and right of the UINavigationBar. I found this accepted answer on how to do this, but I don't really understand how to code it.

I've started by creating a new class called CustomNavBar which inherits from UINavigationBar. I then placed this method in the implementation:

- (void) layoutSubviews
{


}

What I don't understand is the part in the answer that says

call [super layoutSubviews] and then find and reposition the button's view.

How do I code this? Even a nudge in the right direction would be helpful. Thanks!

like image 208
Eric Brotto Avatar asked Nov 10 '11 11:11

Eric Brotto


People also ask

When can I call super layoutSubviews?

For more recent versions of iOS, you should call [super layoutSubviews] at the beginning of your implementation. Otherwise, the superclass will rearrange your subviews after you do the custom layout, effectively ignoring your implementation of layoutSubviews() .

How do I force layoutSubviews?

If you want to force a layout update, call the setNeedsLayout() method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded() method.

When should I use layoutSubviews?

layoutSubviews() The system calls this method whenever it needs to recalculate the frames of views, so you should override it when you want to set frames and specify positioning and sizing. However, you should never call this explicitly when your view hierarchy requires a layout refresh.

What is setNeedsLayout?

setNeedsLayout()Invalidates the current layout of the receiver and triggers a layout update during the next update cycle.


2 Answers

You can loop through the subviews and compare if the current one is the one you want by using NSClassFromString, like this for example:

-(void)layoutSubviews {
    [super layoutSubviews];
    for (UIView *view in self.subviews) {
        if ([view isKindOfClass:NSClassFromString(@"TheClassNameYouWant")]) {
            // Do whatever you want with view here
        }
    }
}

You could also use NSLog in the for loop to see the different subviews.

like image 184
phi Avatar answered Oct 20 '22 17:10

phi


Find the button you want to move after you call layoutSubviews because it will be repositioned to where iOS wants it to be every time layoutSubviews is called.

- (void) layoutSubviews
{
    [super layoutSubviews];

    for (UIView *view in self.subviews) {   // Go through all subviews
        if (view == buttonYouWant) {  // Find the button you want
            view.frame = CGRectOffset(view.frame, 0, -5);   // Move it
        }
    }
}
like image 16
voidStern Avatar answered Oct 20 '22 17:10

voidStern