自定义UIBarButtonItem

3
我是一名有用的助手,可以为您翻译文本。
我有一个自定义按钮,想要添加到导航栏上。所以这是我在我的RootViewController中已经拥有的(它继承了UIViewControllerUINavigationController是通过AppDelegate添加的):
viewDidLoad中:
UIBarButtonItem *share = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon"] style:UIBarButtonItemStylePlain target:self action:@selector(share:)];
self.navigationController.navigationItem.rightBarButtonItem = share;

这是我的UINavigationController设置:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    UIViewController *rootViewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
    [navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"navbar"] forBarMetrics:UIBarMetricsDefault];
    self.window.rootViewController = navigationController;
    [self.window makeKeyAndVisible];
    return YES;
}

为什么这不起作用?

编辑:

我把self.navigationController.navigationItem.rightBarButtonItem替换成了self.navigationItem.rightBarButtonItem,它就起作用了。为什么呢?我的根视图控制器是UIViewController类型的,所以我应该通过navigationController访问navigationItems。在这种情况下,navigationController是什么?

2个回答

1
我将self.navigationController.navigationItem.rightBarButtonItem替换为self.navigationItem.rightBarButtonItem后,它就起作用了。这是为什么呢?
每个UIViewController实例都有一个navigationItem,包括UINavigationController,它是UIViewController的子类。
当新的视图控制器出现时,navigationItem被UINavigationController用于更新其可视状态。当您修改self.navigationController.navigationItem时,您正在修改如果嵌套了UINavigationControllers,则将显示的内容。在实践中,您永远不会修改UINavigationController的navigationItem,因为您不会嵌套导航控制器。
正如您发现的那样,您必须修改视图控制器的navigationItem才能使更改在导航控制器中生效。
在这种情况下,navigationController是什么?
navigationController是指当前包含self表示的视图控制器的UINavigationController的引用。
例如:
UIViewController* viewController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:viewController];

// This is TRUE: viewController.navigationController == navController

好的,所以每个UIViewController都包含一个对其导航控制器的引用,使用属性navigationController。但是,navigationItemUIViewController的属性,而不是UINavigationController的属性(UINavigationController继承它,因为它是UIViewController的子类)。我想这可能是一个常见的误解,即navigationItemUINavigationController的属性。还有一个问题,如果视图控制器没有导航栏,将其作为UINavigationController的属性是否更合理? - darksky
视图控制器不拥有导航栏,导航控制器拥有。想象一下,如果只有导航控制器有一个导航项。这意味着每次出现您的视图控制器时,它都必须显式地重置导航项属性。 - featherless
所以视图控制器有某种对导航栏的“弱”指针?如果视图控制器不拥有它,那么为什么navigationItem是视图控制器的属性?视图控制器和navigationItem之间的关系是什么?一个弱指针? - darksky

-1

根据Apple UINavigationController reference更新导航栏,它指出:

  • 如果新的顶层视图控制器有自定义的左侧栏按钮项,则显示该项。要指定自定义的左侧栏按钮项,请设置视图控制器的导航项的leftBarButtonItem属性。

  • 如果新的顶层视图控制器有自定义的右侧栏按钮项,则显示该项。要指定自定义的右侧栏按钮项,请设置视图控制器的导航项的rightBarButtonItem属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接