首页 > 为什么在viewLoad方法里调用[setToolbarHidden:animated:]不起效果

为什么在viewLoad方法里调用[setToolbarHidden:animated:]不起效果

点击tableView任意一行,跳转至UIWebView,显示相应网页,代码如下:

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];

    BNRCoursesViewController *cvc = [[BNRCoursesViewController alloc] initWithStyle:UITableViewStylePlain];
    UINavigationController *masterNav = [[UINavigationController alloc]initWithRootViewController:cvc]; //将tableVC包含在导航VC中

    BNRWebViewController *wvc =[[BNRWebViewController alloc]init];
    cvc.webViewController = wvc;

    self.window.rootViewController = masterNav;


    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    // Override point for customization after application launch.
    return YES;
}

BNRCoursesViewController.m

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//BNRCoursesViewController.m
    NSDictionary *course = self.courses[indexPath.row];
    self.webViewController.URL = [NSURL  URLWithString:course[@"url"]];
    self.webViewController.title = course[@"title"];
    [self.navigationController pushViewController:self.webViewController animated:YES];
}


练习中要在UIWebView下方添加一个UIToolbar用来放置后退前进的button。
我用了navigation自带的setToolbar方法
[self.navigationController setToolbarHidden:NO animated:YES]
但是发现在viewDidload中使用却没有效果, 在viewWillAppear中却可以成功,
按理来说WebViewController加载viewLoad方法时应该能调用此方法啊,请问为什么不成功呢?

BNRWebViewController.m部分代码如下

#import "BNRWebViewController.h"

@interface BNRWebViewController ()<UIWebViewDelegate>  
@property (nonatomic,strong) UIWebView *webView;
@property (nonatomic, strong) UIBarButtonItem *backButton;
@property (nonatomic, strong) UIBarButtonItem*forwardButton;

@end

@implementation BNRWebViewController

#pragma load
-(void)loadView{           //加载webView
    self.webView = [[UIWebView alloc] init];
    self.webView.scalesPageToFit = YES;
    self.webView.delegate = self;

    self.backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRewind target:self action:@selector(goBack:)];
    self.forwardButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFastForward target:self action:@selector(goForward:)];
    [self.backButton setEnabled:NO];
    [self.forwardButton setEnabled:NO];
    [self setToolbarItems:[NSArray arrayWithObjects:self.backButton,self.forwardButton, nil]];

    self.view = self.webView;
}

-(void)viewDidLoad{
    [super viewDidLoad];
    //[self.navigationController setToolbarHidden:NO animated:YES];  无效
}

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

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

-(void)webViewDidFinishLoad:(UIWebView *)webView {
    [self.backButton setEnabled:[self.webView canGoBack]];
    [self.forwardButton setEnabled:[self.webView canGoForward]];
}


刚才写了个demo测试,将[self.navigationController setToolbarHidden:NO animated:YES];写在viewDidload中是有效果的。是不是楼主其他代码有影响到,代码能否贴详细点..


如果是单页程序,viewWillDisappear不会被调到,楼主无论是使用viewDidLoad 还是 viewWillAppear都是有效的。但是,如果是多页程序,A->B,同时A、B页面都操作了以下方法,那么会有问题。
'''
[self.navigationController setToolbarHidden:NO animated:YES]
[self.navigationController setToolbarHidden:YES animated:YES]
'''

问题的关键在于navigationController是全局的,A页面Disappear的时候恰好B页面已经viewDidLoad完成,会互相干扰。

不知道是不是楼主遇到的问题。


很巧我刚刚也是遇到这个练习和问题,所以专门注册了个帐号来回答你.
首先,这本书真心很不错很不错.
好了进入正题..

@LawrenceHan 同学上面说得很清楚,但是没有正面回答楼主的问题,楼主你提问的是为什么在viewDidLoad里面没效果,在viewWillAppear里面才有,我在这里做一个补充. loadView和viewDidLoad里面获取self.navigationController,它是一个nil,而在viewWillAppear里面获取则是一个真正存在的navigationController.

这很好地说明了为什么只有在viewWillAppear才有效果.至于为什么只有在viewWillAppear里才不是nil,其他两个方法是nil,这个涉及到iOS View 的加载规则了,如果你有兴趣可以去查看详细资料.


这位同学这么巧啊你也是通过 Big Nerd Ranch的书来学习ios开发的啊 :)
这应该是第四版的内容。

分析

你这里使用了loadView做为初始化viewController的view,那么这个方法本身的说明你看了嘛?
注意里面有两段话很重要 (原文我贴在下方):
If you use Interface Builder to create your views and initialize the view controller, you must not override this method.

以及:
If you want to perform any additional initialization of your views, do so in the viewDidLoad method.

解决方案

那么你需要做的就很简单了,把你自定义按钮的方法放到viewDidLoad里去执行就可以了
下面献丑贴一段我当时学习写的代码供你参考(见最下方)

附1:

You should never call this method directly. The view controller calls this method when its view property is requested but is currently nil. This method loads or creates a view and assigns it to the view property.
If the view controller has an associated nib file, this method loads the view from the nib file. A view controller has an associated nib file if the nibName property returns a non-nil value, which occurs if the view controller was instantiated from a storyboard, if you explicitly assigned it a nib file using the initWithNibName:bundle: method, or if iOS finds a nib file in the app bundle with a name based on the view controller'€™s class name. If the view controller does not have an associated nib file, this method creates a plain UIView object instead.
If you use Interface Builder to create your views and initialize the view controller, you must not override this method.
You can override this method in order to create your views manually. If you choose to do so, assign the root view of your view hierarchy to the view property. The views you create should be unique instances and should not be shared with any other view controller object. Your custom implementation of this method should not call super.
If you want to perform any additional initialization of your views, do so in the viewDidLoad method.

附2:

objc#import "BNRWebViewController.h"

@implementation BNRWebViewController
#pragma mark - init methods
- (void)loadView
{
    UIWebView *webView = [[UIWebView alloc] init];
    webView.scalesPageToFit = YES;
    self.view = webView;
}

- (void)setURL:(NSURL *)URL
{
    _URL = URL;
    if (_URL) {
        NSURLRequest *req = [NSURLRequest requestWithURL:_URL];
        [(UIWebView *)self.view loadRequest:req];
    }
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self initToolBar];

}

- (void)initToolBar
{
    NSMutableArray *toolBarItems = [[NSMutableArray alloc] init];
    UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemReply target:self action:@selector(back)];
    UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(forward)];

    UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc]
                                  initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                                  target:self
                                  action:nil];
    [toolBarItems addObject:item1];
    [toolBarItems addObject:flexSpace];
    [toolBarItems addObject:flexSpace];
    [toolBarItems addObject:flexSpace];
    [toolBarItems addObject:flexSpace];
    [toolBarItems addObject:flexSpace];
    [toolBarItems addObject:item2];

    self.toolbarItems = toolBarItems;
    UIWebView *webview = (UIWebView *)self.view;
    if (webview.canGoBack || webview.canGoForward) {
        self.navigationController.toolbarHidden = NO;
    } else {
        self.navigationController.toolbarHidden = YES;
    }

}

- (void)back
{
    UIWebView *webview = (UIWebView *)self.view;
    if (webview.canGoBack) {
        [webview goBack];
    }
}

- (void)forward
{
    UIWebView *webview = (UIWebView *)self.view;
    if (webview.canGoForward) {
        [webview goForward];
    }
}
#pragma mark - UISplitViewController Delegate
- (void)splitViewController:(UISplitViewController *)svc
     willHideViewController:(UIViewController *)aViewController
          withBarButtonItem:(UIBarButtonItem *)barButtonItem
       forPopoverController:(UIPopoverController *)pc
{
    // If the bar button item does not have a title, it will not appear at all
    barButtonItem.title = @"Courses";
    // Take this bar button item and put it on the left side of the nav item
    self.navigationItem.leftBarButtonItem = barButtonItem;
}

- (void)splitViewController:(UISplitViewController *)svc
     willShowViewController:(UIViewController *)aViewController
  invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
    // Remove the bar button item from navigation item
    // Double check that it is the correct button, even though we know it is
    if (barButtonItem == self.navigationItem.leftBarButtonItem) {
        self.navigationItem.leftBarButtonItem = nil;
    }
}
@end 
【热门文章】
【热门文章】