UINavigationBar 和新的 iOS 5+ 外观 API - 如何提供两个背景图像?
Posted
技术标签:
【中文标题】UINavigationBar 和新的 iOS 5+ 外观 API - 如何提供两个背景图像?【英文标题】:UINavigationBar and new iOS 5+ appearance API - how to supply two background images? 【发布时间】:2011-12-07 08:58:43 【问题描述】:我想利用新的 ios 5 外观 API 为我的应用程序中的所有 UINavigationBar 实例提供自定义背景图像。要做到这一点,就这么简单:
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"whatever.png"] forBarMetrics:UIBarMetricsDefault];
但是,对于每个实例,我想根据translucent
属性的值提供不同的图像,例如
// For UINavigationBar instances where translucent returns YES:
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"whatever-translucent.png"] forBarMetrics:UIBarMetricsDefault];
// Otherwise:
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"whatever.png"] forBarMetrics:UIBarMetricsDefault];
鉴于外观 API 似乎是使用类方法配置的,这样的事情可能吗?
【问题讨论】:
【参考方案1】:目前,无法执行您所描述的操作 - 外观代理在您调用它时对任何特定实例一无所知。
实际上,您可能需要做的是弄清楚您有多少半透明条与您有多少非半透明条。选择您拥有的更多并为其使用外观代理 - 对于其他人,当您将其设置为半透明(或要求全屏布局)时,您必须设置背景图像。
与此同时,您能否就您的要求向http://bugreport.apple.com/ 提交增强请求?这不是一个不合理的要求。谢谢!
【讨论】:
是的,这就是我在过去几分钟内想出的内容......谢谢。【参考方案2】:您可以使用类外观代理对其进行全局设置,也可以将其设置在导航栏的实例上。
我目前正在为导航栏的一个实例设置背景,它似乎正在工作。我有两个不同背景的不同导航栏。如果你在一个实例上设置它,你应该能够调节代码。
UINavigationController *myNavController = [[UINavigationController alloc] initWithRootViewController:myView];
[viewControllers addObject:myNavController];
// not supported on iOS4
UINavigationBar *navBar = [myNavController navigationBar];
if ([navBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)])
// right here, you could condition bg image based on properties of this instance
// of the navBar or any other condition.
[navBar setBackgroundImage:[UIImage imageNamed:@"bg.jpg"] forBarMetrics:UIBarMetricsDefault];
如果要使用类方法设置,可以为所有设置:
[[UINavigationBar appearance] setBackground ...
我承认它很新,我只是像大多数人一样弄清楚它。
【讨论】:
我试图在全局范围内实现这一点,对于任何 UINavigationBar 实例,所以实例方法不会削减它 - 本质上,我想使用类方法,但让它设置不同的图像当外观代理将自身应用于每个实例时,基于半透明属性的值......我想我可能不走运...... 我不知道除了在实例级别上执行此操作之外的其他方法 - 这确实会让您乱扔代码但您可以有一个通用的方法来做到这一点。 我在看的另一件事是外观WhenContainedIn,但我认为这也对您没有帮助,因为这更多的是关于控制使用哪种外观的视图类型... 您可能会考虑 UINavigationBar、UINavigationBarTranslucent 或其他的子类,并使用 appearanceWhenContainedIn 类方法。仍然很痛苦,但是您不必为特定实例“乱扔”代码。【参考方案3】:这个答案可能对您没有太大帮助,但对其他人可能有用。如果您创建一个子类,您可以分别指定每个子类的外观。例如,我有 UITableviewCells 和一个从 UITableViewCells 派生的自定义类。实际上我这样做是有原因的,但我发现我需要专门为这两个类调用 [[UITableViewCells appearance] setFont:[...]] 。
由于您似乎希望基于一个直到运行时才知道的变量来执行此操作,所以您可能不走运!
【讨论】:
【参考方案4】:如果你知道哪些类包含半透明条,你可以这样做:
[[UIBarButtonItem appearanceWhenContainedIn:[MyClassWithTranslucentBar class], [MyOtherClassWithTranslucentBar class], nil]
setTintColor:desiredColor];
【讨论】:
【参考方案5】:我不能发表评论,所以必须回答。 Rob Whitlow 就此写了一篇很棒的文章。看看吧:http://ios-blog.co.uk/tutorials/ios-custom-ui-series-tabbar-navbar/
【讨论】:
【参考方案6】:试试这个:
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1)
// Load resources for iOS 6.1 or earlier
navigationController1 = [self customizedNavigationController];
[navigationController1 setViewControllers:[NSArray arrayWithObject: self.homeViewController]];
[self setNavigationController:navigationController1];
[self.window setRootViewController:navigationController];
else
// Load resources for iOS 7 or later
navigationController1 = [[UINavigationController alloc] initWithRootViewController:self.homeViewController];
[self.window setRootViewController:navigationController1];
- (UINavigationController *)customizedNavigationController
UINavigationController *navController = [[UINavigationController alloc] initWithNibName:nil bundle:nil];
// Ensure the UINavigationBar is created so that it can be archived. If we do not access the
// navigation bar then it will not be allocated, and thus, it will not be archived by the
// NSKeyedArchvier.
[navController navigationBar];
// Archive the navigation controller.
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:navController forKey:@"root"];
[archiver finishEncoding];
// Unarchive the navigation controller and ensure that our UINavigationBar subclass is used.
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
[unarchiver setClass:[LNTNavigationBar class] forClassName:@"UINavigationBar"];
UINavigationController *customizedNavController = [unarchiver decodeObjectForKey:@"root"];
[unarchiver finishDecoding];
// Modify the navigation bar to have a background image.
LNTNavigationBar *navBar = (LNTNavigationBar *)[customizedNavController navigationBar];
[navBar setTintColor:[UIColor colorWithRed:0.39 green:0.72 blue:0.62 alpha:1.0]];
[navBar setBackgroundImage:[UIImage imageNamed:@"nav_bar_1024_46.png"] forBarMetrics:UIBarMetricsDefault];
[navBar setBackgroundImage:[UIImage imageNamed:@"nav_bar_1024_46.png"] forBarMetrics:UIBarMetricsLandscapePhone];
return customizedNavController;
【讨论】:
以上是关于UINavigationBar 和新的 iOS 5+ 外观 API - 如何提供两个背景图像?的主要内容,如果未能解决你的问题,请参考以下文章
新的ios5api:自定义UINavigationBar背景属性与简单的功能!!!
iOS 应用程序在更新到新版本和新的 firebasedb 后崩溃
iOS 5 - 1 自定义 UINavigationBar 不同于所有其他
UINavigationBar 自定义背景与悬垂(iOS 5)
为所有导航栏 (UINavigationBar) iOS 5.1+ 设置按钮和外观
嵌入 UISplitViewController 时,UINavigationBar 中缺少 iOS11 UISearchBar