UINavigationBar和新iOS 5+外观API - 如何提供两个背景图片?

8

我希望利用新的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似乎是使用类方法配置的,这种情况类似于可能吗?
6个回答

4
你可以通过类外观代理全局设置,也可以在导航栏的实例上进行设置。
我目前正在为导航栏的实例设置背景,并且似乎正在工作中。我有两个不同的导航栏,具有不同的背景。如果你在实例上设置它,你应该能够对代码进行条件约束。
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实例都是如此,因此实例方法行不通 - 本质上,我想使用类方法,但是当外观代理应用于每个实例时,它将根据透明度属性的值设置不同的图像...我想我可能没有机会了... - Mark Beaton
我不知道除了在实例级别上执行之外还有其他方法来做到这一点 - 这会让你的代码变得混乱,但你可以有一个通用的方法来完成这个任务。 - bryanmac
我看过的另一件事是appearanceWhenContainedIn,但我认为那也不能帮助你,因为它更多地涉及控制它所在的视图类型以使用哪种外观... - bryanmac
你可以考虑使用UINavigationBar的子类,例如UINavigationBarTranslucent,并使用appearanceWhenContainedIn类方法。虽然仍然有些麻烦,但这样你就不必为特定实例“弄乱”你的代码了。 - sean woodward

4
目前还没有方法可以实现您所描述的功能-外观代理不知道在调用它时有关特定实例的任何信息。
从实际角度看,您可能需要确定您有多少个半透明栏和非半透明栏。选择其中一个使用外观代理-对于其他栏,当您要使其半透明(或请求全屏布局)时,您将不得不设置背景图像。
与此同时,您可以在http://bugreport.apple.com/上提出增强请求来实现您的要求。这并不是一个不合理的请求。谢谢!

是的,这基本上就是我在过去几分钟里弄清楚的...谢谢。 - Mark Beaton

1
如果您知道哪些类包含半透明的条形,则可以像这样操作:
[[UIBarButtonItem appearanceWhenContainedIn:[MyClassWithTranslucentBar class], [MyOtherClassWithTranslucentBar class], nil]
    setTintColor:desiredColor];

1

这个答案可能对你没什么帮助,但对其他人可能有用。如果你创建一个子类,可以为每个子类单独指定外观。例如,我有UITableviewCells和从UITableViewCells派生的自定义类。我实际上是出于某种原因这样做的,但我发现我需要分别为两个类调用[[UITableViewCells appearance] setFont:[...]]。

由于你似乎想根据在运行时不知道的变量来这样做,所以你可能没有办法!


0

试试这个:

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;
}

0

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