2015-07-19 120 views
0

我一直在研究如何为iOS应用程序创建配色方案。iOS应用程序的配色方案 - UIView和UIAppearance - 设置背景颜色

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

这导致我找到UIAppearance协议,我想,作为一个起点,如何只是在做这样的事情:

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

我在Xcode 6试验和使用主从应用程序模板(目标-C)。结果并非我所期望的;我预计该应用看起来与之前一样,但具有橙色背景。我实际上得到的是整个应用程序显示为橙色的单个全屏矩形,无法查看UI的实际元素。它看起来像前景和背景颜色都设置为橙色,没有区别(我会张贴我看到的图像,但我目前没有足够的声誉)。我也尝试使用setTintColor,但这似乎影响的唯一UI元素是UITableView的“编辑”并添加其文本设置为橙色的“+”按钮。

我能够通过设置以下以获得基本上由“预期”的结果(在下面的代码段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]]; 

我知道这并没有太多的代码,它允许对外观进行更细致的控制(只有坚实的橙色可能不是最好的外观!),但它留下的东西我不明白,如果我不'不明白,那么可能有未知的陷阱,所以我的问题是:

  1. 为什么不简单地设置UIView的背景颜色实际上是为所有视图设置背景颜色(而不是使前景和背景同一)?
  2. 对于UINavigationBar,setBackgroundColor:似乎没有效果,只有setBarTintColor:具有预期的结果。这种行为似乎并不一致;有谁知道这是为什么?
  3. Bonus问题:是否有任何方法可以设置全班级的UITableViewCell的背景颜色?我遇到的唯一方法是实例属性'selectedBackgroundView',一个选项是将其子类化并在指定的初始化程序中设置给定的颜色,但有没有更好的方法?

正如你可能从这个问题可以告诉我,我是新的iOS开发;我的背景是服务器端C++,而且我正在与Objective-C合作,因为它离我的舒适区更近一点,Swift似乎也是目前的移动目标。

回答

0

我也是相对较新的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我找到的最简单的方法是继承,并覆盖setHighlightedsetSelectedselectedBackgroundView,如果您认为合适的话。

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

- (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子视图UITableViewCell S的:

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

你可以使用这个调用来昌e全球任何元素。它使您能够更细致地控制要更改的元素。例如包含在UIToolBar唯一当

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

将改变栏按钮项目的tintColor。包含在UIToolBar■当

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

将改变栏按钮项的字体。

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

例如,假设您有一个自定义UITableViewCell,您希望将其中一个标签指定为应用正在使用的任何色调颜色。所以,你重写tintColorDidChange像这样:

- (void)tintColorDidChange 
{ 
    [self.label setTextColor:self.tintColor]; 
} 

然后当你在UIViewController

self.view.tintColor = [UIColor orangeColor]; 

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

至于setTintColor只更改UIBarButtonItem s。更改UINavigationBar上的tintColor也会更改所有子视图中的tintColor,这意味着在这种情况下,UINavigationBarItem上的tintColor被更改,它们将其用作标题textColor

希望这会有所帮助。

+0

谢谢克里斯,你的回答帮助我解决了一些其他我着色过的实际问题。你指出能够基于层次结构进行着色的部分特别有用,因为当我在研究嵌入式UITableView时,无法一直获得正确的颜色。 我不太确定的一件事仍然是背景颜色的UIView设置。我得到了几乎所有从UIView继承而来的设置,并且为所有设置了背景颜色,但是我不明白为什么会隐藏以前可见的任何“前景”颜色。 – DragonTheHorse

+0

太棒了!乐意效劳。至于'UIView'问题。如果我正确阅读,我认为发生的事情又是所有的意见都将'backgroundColor'设置为橙色。为了澄清,我的意思是即使'UILabel'继承自'UIView' - 所以即使他们的'backgroundColor'也会变成橙色。但是,如果你说即使'textColor'变成橙色,那也是奇怪的。我不确定为什么会这样。也许如果你用前景色详细说明你的意思,我可以帮助更多。 – Kris

+0

外观就像'textColor'这样的东西也被设置为橙色,所以即使画布上的标签也是不可见的,因为它们与背景颜色相同(并且在故事板中textColor是黑色的) 。这可能不是实际发生的事情,它只是看起来发生了什么。也许在默认应用程序模板的前景中有一个通常是透明的全屏视图 - 如果这样,我当然可以理解,将其背景设置为纯橙将会蚀掉应用程序中的其他所有内容 – DragonTheHorse