为什么在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]];
}

图片描述

uinavigationcontroller ios objective-c

bee配音 10 years, 7 months ago

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

魂狩D骑士 answered 10 years, 7 months ago

这位同学这么巧啊你也是通过 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

愤怒的小土豆 answered 10 years, 7 months ago

Your Answer