Reputation: 8880
I have an ipad app where i would like to hide and show a category list (kind of like the small view in a split view controller), and the main view which contains a UiNavigationController stack.
I would like to resize the UINavigationController view to fill the whole screen when the category list is hidden, and to shrink when i show the list.
I have it working, except the title of the navigation bar immediately jumps to its new offset when setting the frame within an animation begin/commit block.
Any ideas how to stop the jump of the title?
Upvotes: 7
Views: 2881
Reputation: 51
It worked fine for me when I included [self.navigationController.navigationBar layoutSubviews]
in the animation block itself.
Here's the code example:
[UIView animateWithDuration:0.5
animations:^{
[self.navigationController.navigationBar setFrame:newFrame];
[self.navigationController.navigationBar layoutSubviews];
}];
I hope this is somehow helpful.
Upvotes: 1
Reputation: 8880
My solution, seems to cope with all scenarios I hit in my app. Obviously still a bit of a hack, so no guarantees it will always work!
@implementation UINavigationBar (Nick)
- (void)layoutSubviews {
[super layoutSubviews];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
UIView* titleView = nil;
CGFloat buttonWidths = 0;
for (UIView* subview in [self subviews]) {
if ([subview class] == NSClassFromString(@"UINavigationItemView")) {
if (titleView) {
// Exit here - if there is more than one title, probably doing a pop
return;
}
titleView = subview;
}
else if ([subview class] == [UIView class] || // bar button with custom view
[subview class] == NSClassFromString(@"UINavigationButton")) { // or ordinary bar button
buttonWidths += subview.frame.size.width;
// is it RHS?
if (subview.frame.origin.x > subview.frame.size.width) {
[subview setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
}
else {
[subview setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin];
}
}
else if ([subview class] == NSClassFromString(@"UINavigationItemButtonView")) {
// pretty sure this is always the back button
buttonWidths += subview.frame.size.width;
[subview setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin];
}
}
if (titleView) {
buttonWidths += 20; // seems to be apple indentation
CGRect rect = titleView.frame;
if (rect.size.width > self.frame.size.width - buttonWidths) {
rect.size.width = self.frame.size.width - buttonWidths;
titleView.frame = rect;
}
titleView.center = self.center;
}
}
}
Upvotes: 1
Reputation: 158
I used this for fixing those jumps in UINavigationBar for title and right button.
#import "UINavigationBar+My.h"
@implementation UINavigationBar (My)
- (void)layoutSubviews {
for (id obj in [self subviews]) {
if ([NSStringFromClass([obj class]) isEqualToString:@"UINavigationItemView"])
[(UIView *)obj setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin];
else if ([NSStringFromClass([obj class]) isEqualToString:@"UIButton"]) {
if ([(UIButton *)obj center].x < ([self center].x / 2))
[(UIButton *)obj setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin];
else
[(UIButton *)obj setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
}
}
@end
I hope it will help you ;-)
Upvotes: 3
Reputation: 5941
I ran into a similar problem recently; I had a subview of the animating view that was jumping immediately to its new position. This was happening because -layoutSubviews
was being called on that view as a result of me programmatically modifying it before the animation finished. Are you doing something like changing the text of the title or modifying it in some way that would cause -layoutSubviews
to be called on it?
Upvotes: 2