iOS 应用的配色方案 - UIView 和 UIAppearance - 设置背景颜色

Posted

技术标签:

【中文标题】iOS 应用的配色方案 - UIView 和 UIAppearance - 设置背景颜色【英文标题】:Colour Scheme for an iOS App - UIView and UIAppearance - Setting the Background Colour 【发布时间】:2015-07-19 15:59:48 【问题描述】:

我一直在研究如何为 ios 应用创建配色方案。

从故事板开始并为每个组件手动设置背景颜色后,我很快意识到,虽然对于玩具应用程序来说这很好,但对于任何更复杂的应用程序来说,这既乏味又耗时 - 特别是如果你想在未来再次改变所有的颜色。

这让我找到了 UIAppearance 协议,我想,作为一个起点,做这样的事情怎么样:

[[UIView appearance] setBackgroundColor:[UIColor orangeColor]];

我正在试验 Xcode 6 并使用 Master-Detail App Template (Objective-C)。结果出乎我的意料;我希望这个应用看起来和以前一样,但背景是橙色的。我实际上得到的是整个应用程序显示为一个橙色的全屏矩形,无法查看 UI 的实际元素。它实际上看起来前景和背景颜色都设置为橙色,没有区别(我会发布我所看到的图像,但我目前没有足够的声誉这样做)。我也尝试过使用 setTintColor,但这似乎影响的唯一 UI 元素是 UITableView 的“编辑”和添加文本设置为橙色的“+”按钮。

通过设置以下内容,我基本上可以获得“预期”结果(下面 sn-p 中的 DetailViewUIAppearanceTest 是 UIView 的未修改子类,我将其设置为用于详细视图):

[[UITableView appearance] setBackgroundColor:[UIColor orangeColor]];
[[UITableViewCell appearance] setBackgroundColor:[UIColor orangeColor]];
[[UINavigationBar appearance] setBarTintColor:[UIColor orangeColor]];
[[DetailViewUIAppearanceTest appearance] setBackgroundColor:[UIColor orangeColor]];
[[UILabel appearance] setBackgroundColor:[UIColor orangeColor]];

我知道这并没有更多的代码,它允许对外观进行更细粒度的控制(毕竟纯橙色可能不是最好的外观!),但它留下了我不理解的东西,如果我不明白那么可能会有无法预料的陷阱,所以我的问题是:

    为什么不简单地设置 UIView 的背景颜色,而不是实际设置所有视图的背景颜色(而不是使前景和背景相同)? 对于 UINavigationBar,setBackgroundColor: 似乎没有效果,只有 setBarTintColor: 有预期的结果。这种行为似乎不一致;有谁知道为什么会这样? Bonus 问题:有没有办法在类范围内设置选定 UITableViewCell 的背景颜色?我遇到的唯一方法是实例属性“selectedBackgroundView”,一种选择是对其进行子类化并在指定的初始化程序中设置给定的颜色,但有更好的方法吗?

您可能从问题中可以看出,我是 iOS 开发的新手;我的背景是服务器端 C++,我正在使用 Objective-C,因为它更接近我的舒适区,而且 Swift 目前似乎是一个移动目标。

【问题讨论】:

【参考方案1】:

我对 Objective-c 开发也比较陌生,但让我在这里尝试帮助您。

[[UIView appearance] setBackgroundColor:[UIColor orangeColor]];

这导致整个屏幕变成橙色,因为您告诉屏幕上的每个视图都将其背景颜色设置为橙色。屏幕上的所有内容都是UIView 的子类——这意味着UITableViewUIScrollView 等。这就是为什么您需要更细粒度地调用setBackgroundColor 和其他相关方法。

[[UINavigationBar appearance] setBarTintColor:[UIColor orangeColor]];

至于UINavigationBar,就是这样设计的。根据文档:barTintColortint color to apply to the navigation bar background. 直接设置backgroundColor 不会有效果。这是元素的设计方式。也许其他人可以给出更详细的原因。

还要全局更改UITableViewCell,我发现最简单的方法是子类化,并根据您的需要覆盖setHighlighted setSelectedselectedBackgroundView

如果你想覆盖高亮颜色以及选择的颜色(并支持动画),我之前所做的是:

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated

    [super setHighlighted:highlighted animated:animated];

    NSTimeInterval duration = animated ? .25f : 0.f;

    if (highlighted)
    
        [self animateBackgroundTo:[UIColor orangeColor] duration:duration];
     
    else
    
        [self animateBackgroundTo:[UIColor whiteColor] duration:duration];
    


- (void)animateBackgroundTo:(UIColor *)backgroundColor duration:(NSTimeInterval)duration

    [UIView animateKeyframesWithDuration:duration delay:0 options:UIViewKeyframeAnimationOptionAllowUserInteraction animations:^
            self.backgroundColor = backgroundColor;
         completion:nil];

如果您不想继承UITableViewCell,而只想更改其backgroundColor,则可以使用UIAppearance,这将更改backgroundColorcontentView 子视图@987654341 @s:

[[UIView appearanceWhenContainedIn:[UITableViewCell class], nil] setBackgroundColor:[UIColor orangeColor]];

您可以使用此调用全局更改任何元素。它使您可以进一步细粒度地控制要更改的元素。例如

[[UIBarButtonItem appearanceWhenContainedIn:[UIToolbar class], nil] setTintColor:[UIColor orangeColor]];

仅当包含在UIToolBars 中时才会更改条形按钮项目的 tintColor。

[[UIBarButtonItem appearanceWhenContainedIn:[UIToolbar class], nil] setTitleTextAttributes:@NSFontAttributeName:[UIFont boldSystemFontOfSize:16.f] forState:UIControlStateNormal];

当包含在UIToolBars 中时,将更改条形按钮项目的字体。

编辑: tintColor 属性在为您的应用程序设置主题时非常方便。您可以在任何视图中使用它(它从UIViewController 的主视图通过视图层次结构向下传递)来设置任何元素的颜色。

例如,假设您有一个自定义 UITableViewCell,您希望其中一个标签是您的应用使用的任何色调颜色。所以你像这样覆盖tintColorDidChange

- (void)tintColorDidChange

    [self.label setTextColor:self.tintColor];

然后当你设置你的UIViewController

self.view.tintColor = [UIColor orangeColor];

神奇的是,您的单元格现在会有橙色标签! (您需要通过调用reloadData 或类似方法重新绘制单元格)

至于setTintColor,仅更改UIBarButtonItems。更改UINavigationBar 上的tintColor 也会更改所有子视图的tintColor,这意味着在这种情况下UINavigationBarItems 上的tintColor 已更改,它们将其用作标题textColor

希望这会有所帮助。

【讨论】:

感谢 Kris,您的回答帮助我解决了我在着色方面遇到的其他一些实际问题。您指出的关于能够基于层次结构着色的部分特别有用,因为当我在嵌入式 UITableView 上工作并且无法始终正确地获得颜色时。我不太确定的一件事是背景颜色的 UIView 设置。我得到了几乎所有东西都继承自 UIView 并且您正在为所有人设置背景颜色,但我不明白为什么这会使以前可见的任何“前景”颜色黯然失色。 太好了!乐意效劳。至于UIView 问题。如果我阅读正确,我认为再次发生的事情是所有视图都将backgroundColor 设置为橙色。澄清一下,我的意思是即使UILabels 也继承自UIView - 所以即使他们的backgroundColor 也会变成橙色。但是,如果您说即使 textColor 也被更改为橙色,那很奇怪。我不确定为什么会这样。也许如果您详细说明前景色的含义,我可以提供更多帮助。 外观就像textColor 之类的东西也被设置为橙色,所以即使是画布上的标签也是不可见的,因为它们与背景颜色相同(在情节提要中) textColor 是黑色的)。这实际上可能不是正在发生的事情,它只是似乎正在发生的事情。也许在默认应用模板的前景中有一个通常是透明的全屏视图 - 如果是这样,我当然可以理解将其背景设置为纯橙色会使应用中的其他所有内容黯然失色 我尝试通过 Xcode 6 的 3d 视图调试器运行并在其中(全局设置 UIViewbackgroundColor),在调试器中,UI 看起来与它应该的完全一样,并且没有任何迹象前面有一个模糊的窗口,而在模拟器上我只是得到了没有任何标签文本迹象的纯橙色块。 这当然很奇怪!是的,我知道的不够诚实,无法回答这个问题。也许其他人会参与进来。知道为什么会很有趣。你在设备上试过了吗?

以上是关于iOS 应用的配色方案 - UIView 和 UIAppearance - 设置背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

UI UIView

iOS开发UI篇—核心动画(UIView封装动画)

拿来即用的配色大全-UI设计师必备

使用动态颜色创建 UI 的最佳方法 [关闭]

在 SceneKit 中使用 GIFU 库播放 GIF 会导致应用程序 UI 冻结任何解决方案? UIView Animated 从后台线程调用

iOS开发-UI 补充 UIWindow UIView UIlabel