Hiding a UINavigationController's UIToolbar during viewWillDisappear:

后端 未结 11 1720

I\'ve got an iPhone application with a UITableView menu. When a row in the table is selected, the appropriate view controller is pushed onto the application\'s

相关标签:
11条回答
  • 2021-02-03 21:25

    The issue here is that the UITableView's frame is set so that it does not overlap with the UIToolbar. That is, it sits just above the UIToolbar. When you push the next UIViewController to the UINavigationController stack, while removing the UIToolbar, there is nothing to show but the UIWindow behind it, unless you put something there in its place.

    One workaround without the awkward animation after transition is to place your UITableView in a UIView "container" that shares the same frame as your regular view, but underlaps the UIToolbar with the desired colour that you wish to see during the transition (e.g. white).

    To enact the underlap, you could set your UIViewController to wantsFullScreenLayout = YES. You would then ensure that your UITableView has the same frame as it would have before the use of the container. i.e. it sits below the navigation bar, and above the toolbar.

    This can be made more elegant by writing a custom UIViewController and use that instead of the UITableViewController, or by being sneaky and inserting the new UIView "container" beneath the UITableView in your existing UITableViewController.

    0 讨论(0)
  • 2021-02-03 21:27

    I wasn't satisfied with the answers on this question so I posted my own: Reference to source view controller and destination view controller at the same time

    The answer I got fixed my problem. It may work for yours too (though this question is pretty old, I figured this might help someone like me who read this post a half dozen times looking for a hint).

    Here's what I did. I don't know if marker protocols are idiomatic objective-c or not, but I liken them to attributes like I'd use in c# so I have this marker protocol:

    @protocol HidesNavigationItem
    @end
    

    I added UINavigationControllerDelegate to my AppDelegate. I'm not sure yet whether or not that's a good thing. I thought about keeping that implementation in another object, but for now, this is where I put it. Here's the implementation:

    #pragma mark Navigation Controller Delegate
    -(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        [navigationController setNavigationBarHidden:[viewController conformsToProtocol:@protocol(HidesNavigationItem)] animated:animated];
    }
    

    This way, I can just set my marker protocol on my UIViewController implementation like so:

    @interface MyViewController : UIViewController <HidesNavigationItem>
    

    If I don't have that interface, it puts it back.

    Finally, in my appDelegate's application:didFinishLaunchingWithOptions: method, I wire up the delegate like this:

    if ([self.window.rootViewController isMemberOfClass:[UINavigationController class]])
        ((UINavigationController*)self.window.rootViewController).delegate = self;
    

    Now I get no black boxes and no Cheshire Cat. My solution was with regard to the navigation bar of course, but I'm sure it works the same for the toolbar. This is very similar to Danra's answer except that I get the black box without the "animated:animated."

    0 讨论(0)
  • 2021-02-03 21:29

    I am in agreement with Jeff's answer. But there is a UI glitch if I hide the toolbar in -viewDidAppear method of the viewController through which different viewControllers are pushed.

    To avoid this, I was experimenting and found out that calling -setToolbarHidden in the -viewWillAppear call indeed hides the toolbar, but as the question states, the view though expanded would not be occupied by the tableview rows.

    To fix this, I have changed to following code and now it works without the glitch:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    .
    .
    .
        [self reframeRowHeight];
        [self.menuItemTableView addObserver:self
                                 forKeyPath:@"frame"
                                    options:NSKeyValueObservingOptionNew
                                    context:nil];
        [self.menuItemTableView setBounces:NO];
    .
    .
    .
    }
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        if ([keyPath isEqualToString:@"frame"])
        {
            [self reframeRowHeight];
        }
    }
    
    -(void)reframeRowHeight
    {
    
        [self.menuItemTableView setRowHeight:self.menuItemTableView.frame.size.height/self.menuItems.count];
        [self.menuItemTableView reloadData];
    }
    
    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
    .
    .
    .
        // Bad Apple! - http://stackoverflow.com/questions/2339721/hiding-a-uinavigationcontrollers-uitoolbar-during-viewwilldisappear
        [self.navigationController setToolbarHidden:YES animated:YES];
    .
    .
    .
    }
    
    0 讨论(0)
  • 2021-02-03 21:30

    Managing the toolbar state (i.e. which VC needs/doesn't need the toolbar) gets tricky quickly.

    I've had success with following this rule:

    For each view controller, in viewWillAppear(), decide if it needs a toolbar or doesn't, then call navigationController?.setToolbarHidden(true or false, animated: animated) respectively.

    This way, each view controller starts out with the correct toolbar state and you don't have to worry about "restoring" the toolbar state when the view controller is dismissed.

    0 讨论(0)
  • 2021-02-03 21:32

    To show toolbar in new view controller just add this:

    - (void)viewWillAppear:(BOOL)animated
    {
        [self.navigationController setToolbarHidden:NO animated:animated];
        [super viewWillAppear:animated];
    }
    

    To hide toolbar:

    - (void)viewWillAppear:(BOOL)animated
    {
        [self.navigationController setToolbarHidden:YES animated:animated];
        [super viewWillAppear:animated];
    }
    

    When traveling between screens push new view controller with following code:

    SettingsRecordingViewController *vc = [[SettingsRecordingViewController alloc] initWithNibName:@"SettingsRecordingViewController" bundle:[NSBundle mainBundle]]; 
    [self.navigationController pushViewController:vc animated:YES];      
    [vc release];
    

    and if it has different state of toolbar (hidden/shown) then nice animation of hiding/showing toolbar will be shown.

    0 讨论(0)
  • 2021-02-03 21:36

    I use a custom background image for the toolbar background, and a custom image for the table background. I was having the same issue with the black bar at the bottom as the view transitioned back and forth from another table view. However I set the

    self.navigationController.toolbar.barStyle = UIBarStyleBlackTranslucent;
    

    in viewDidLoad.

    This sets the background image to the full potential size of the background, which if you had a transparent toolbar would make sense. It's probably not a good workaround when you're using the standard opaque toolbar, but for those of you customizing the toolbar anyway, you can get the best of both worlds.

    0 讨论(0)
提交回复
热议问题