美文网首页
UIKit框架(四十五) —— 支持DarkMode的简单示例(

UIKit框架(四十五) —— 支持DarkMode的简单示例(

作者: 刀客传奇 | 来源:发表于2020-07-24 15:28 被阅读0次

    版本记录

    版本号 时间
    V1.0 2020.07.24 星期五

    前言

    iOS中有关视图控件用户能看到的都在UIKit框架里面,用户交互也是通过UIKit进行的。感兴趣的参考上面几篇文章。
    1. UIKit框架(一) —— UIKit动力学和移动效果(一)
    2. UIKit框架(二) —— UIKit动力学和移动效果(二)
    3. UIKit框架(三) —— UICollectionViewCell的扩张效果的实现(一)
    4. UIKit框架(四) —— UICollectionViewCell的扩张效果的实现(二)
    5. UIKit框架(五) —— 自定义控件:可重复使用的滑块(一)
    6. UIKit框架(六) —— 自定义控件:可重复使用的滑块(二)
    7. UIKit框架(七) —— 动态尺寸UITableViewCell的实现(一)
    8. UIKit框架(八) —— 动态尺寸UITableViewCell的实现(二)
    9. UIKit框架(九) —— UICollectionView的数据异步预加载(一)
    10. UIKit框架(十) —— UICollectionView的数据异步预加载(二)
    11. UIKit框架(十一) —— UICollectionView的重用、选择和重排序(一)
    12. UIKit框架(十二) —— UICollectionView的重用、选择和重排序(二)
    13. UIKit框架(十三) —— 如何创建自己的侧滑式面板导航(一)
    14. UIKit框架(十四) —— 如何创建自己的侧滑式面板导航(二)
    15. UIKit框架(十五) —— 基于自定义UICollectionViewLayout布局的简单示例(一)
    16. UIKit框架(十六) —— 基于自定义UICollectionViewLayout布局的简单示例(二)
    17. UIKit框架(十七) —— 基于自定义UICollectionViewLayout布局的简单示例(三)
    18. UIKit框架(十八) —— 基于CALayer属性的一种3D边栏动画的实现(一)
    19. UIKit框架(十九) —— 基于CALayer属性的一种3D边栏动画的实现(二)
    20. UIKit框架(二十) —— 基于UILabel跑马灯类似效果的实现(一)
    21. UIKit框架(二十一) —— UIStackView的使用(一)
    22. UIKit框架(二十二) —— 基于UIPresentationController的自定义viewController的转场和展示(一)
    23. UIKit框架(二十三) —— 基于UIPresentationController的自定义viewController的转场和展示(二)
    24. UIKit框架(二十四) —— 基于UICollectionViews和Drag-Drop在两个APP间的使用示例 (一)
    25. UIKit框架(二十五) —— 基于UICollectionViews和Drag-Drop在两个APP间的使用示例 (二)
    26. UIKit框架(二十六) —— UICollectionView的自定义布局 (一)
    27. UIKit框架(二十七) —— UICollectionView的自定义布局 (二)
    28. UIKit框架(二十八) —— 一个UISplitViewController的简单实用示例 (一)
    29. UIKit框架(二十九) —— 一个UISplitViewController的简单实用示例 (二)
    30. UIKit框架(三十) —— 基于UICollectionViewCompositionalLayout API的UICollectionViews布局的简单示例(一)
    31. UIKit框架(三十一) —— 基于UICollectionViewCompositionalLayout API的UICollectionViews布局的简单示例(二)
    32. UIKit框架(三十二) —— 替换Peek and Pop交互的基于iOS13的Context Menus(一)
    33. UIKit框架(三十三) —— 替换Peek and Pop交互的基于iOS13的Context Menus(二)
    34. UIKit框架(三十四) —— Accessibility的使用(一)
    35. UIKit框架(三十五) —— Accessibility的使用(二)
    36. UIKit框架(三十六) —— UICollectionView UICollectionViewDiffableDataSource的使用(一)
    37. UIKit框架(三十七) —— UICollectionView UICollectionViewDiffableDataSource的使用(二)
    38. UIKit框架(三十八) —— 基于CollectionView转盘效果的实现(一)
    39. UIKit框架(三十九) —— iOS 13中UISearchController 和 UISearchBar的新更改(一)
    40. UIKit框架(四十) —— iOS 13中UISearchController 和 UISearchBar的新更改(二)
    41. UIKit框架(四十一) —— 使用协议构建自定义Collection(一)
    42. UIKit框架(四十二) —— 使用协议构建自定义Collection(二)
    43. UIKit框架(四十三) —— CALayer的简单实用示例(一)
    44. UIKit框架(四十四) —— CALayer的简单实用示例(二)

    开始

    首先看下主要内容:

    在本教程中,您将学习如何在应用程序中添加对黑暗模式的支持,使其在低光照环境下看起来更好。内容来自翻译

    接着看下写作环境:

    Swift 5, iOS 13, Xcode 11

    下面就是正文了。

    苹果在2013年推出iOS7的现代扁平化设计时,许多人都反对其用户界面过白。他们希望使用iOS以前版本中看起来更自然的材料。

    iOS 13出现之前的几年中,许多应用程序都添加了新的颜色主题Dark Mode,以补偿系统的亮度。此主题帮助人们在光线较暗的环境中使用应用程序。

    幸运的是,在iOS13中,Apple决定授予此功能系统级的厚爱。苹果公司的工程师添加了一个切换开关,供用户在浅色和深色外观之间切换。他们还更新了所有预装的应用程序,以尊重用户的选择。

    也许乔尼·艾夫(Jony Ive)离开时占据了所有白色房间!苹果决定拥抱黑暗模式,那为什么不呢?

    在本教程中,您将向Dark Arts添加黑暗模式,这是一个包含有关在HogwartsDefense Against the Dark Arts的所有老师的信息的应用程序。

    具体来说,您将介绍如何:

    • 1) 使用颜色;系统,语义,动态,背景和前景。
    • 2) 支撑高程级别在黑暗模式下起作用。
    • 3) 在light and dark模式下使用其他资源。
    • 4) 利用SF Symbols的力量。
    • 5) 如果您愿意,请退出暗模式。
    • 6) 和更多..

    打开本教程的入门项目。 双击DarkArts.xcodeprojXcode打开项目。

    熟悉项目的源代码和文件结构。

    构建并运行。 您会看到所有Defense Against the Dark Arts老师的列表,这些列表按哈利·波特和朋友们与他们一起学习的年份排序。 点击任何项目以查看更多信息。

    该应用程序的用户界面很明亮。 在学习本教程时,将其删除。

    要查看应用程序当前在黑暗模式Dark Mode下的外观,请在模拟器中运行该应用程序,并按如下所示更改界面样式。

    通过Xcode运行应用程序时,一组调试按钮会显示在底部。 单击Environment Overrides按钮,将出现一个弹出窗口。 弹出窗口顶部有一个Interface Style切换开关。

    现在切换Interface Style开关,然后单击Dark。 该应用程序将如下所示:

    不是您所希望的那么暗吧? 至少导航栏背景切换为黑色。 但是名单列表仍然是白的。


    System Colors

    采用新主题的最重要方面是色彩。 在iOS 13中,Apple对色彩进行了大修,并引入了一些新概念。

    只要存在UIKit,它就提供了一些预定义的颜色,例如.red,.blue.yellow,您可以在UIColor上进行静态访问。

    现在有一个新的调色板以单词system开头,包括.systemRed.systemBlue。 这些颜色在浅色和深色背景上均提供合适且清晰的阴影。

    请参阅Apple Human Interface Guidelines中的此表。 如您所见,每种系统颜色(也称为tint color)对于明暗模式都有不同的RGB颜色代码。

    在应用程序中点击Alastor Moody。 在详细信息屏幕中,教师的霍格沃茨房子的名称以该房子的旗帜颜色显示。 例如,Alastor Moody来自Hufflepuff,因此标记为黄色。

    您可能看不到房屋名称,因为颜色是旧的.yellow。 它不能适应在浅色和深色背景上看起来不错的情况,但是您很快就会解决。

    打开TeacherDetailViewController.swift。 在viewDidLoad()中,设置houseLabel的文本颜色。

    将所有颜色更改为其各自的system变体:

    switch teacher.house {
    case .gryffindor:
      houseLabel.textColor = .systemRed
    case .hufflepuff:
      houseLabel.textColor = .systemYellow
    case .ravenclaw:
      houseLabel.textColor = .systemBlue
    case .slytherin:
      houseLabel.textColor = .systemGreen
    }
    

    构建并运行。 再次点击Alastor Moody。 现在,您可以看到他来自赫奇帕奇(Hufflepuff)


    Semantic Colors

    除了新引入的系统颜色外,iOS 13还提供了语义(semantically)定义的颜色。语义颜色(semantic color)传达其目的,而不是其外观或颜色值。因此,语义颜色也会自动适应黑暗模式。

    您不必知道这些颜色的真实原始值。相反,您可以根据意图使用它们,并像访问其他颜色一样访问它们:通过对UIColor进行静态调用。语义颜色的示例包括.label,.separator,.link,.systemBackground.systemFill

    1. Background Colors

    iOS定义了两组背景色:systemgrouped。每个变量都包含主要,次要和第三级变体,可帮助您传达信息的层次结构。

    通常,当您具有分组表格视图(grouped table view)时,请使用分组(grouped set)的背景颜色集。否则,请使用系统设置(system set)的背景色。

    对于这两种背景色,您都可以使用变体通过以下方式显示层次结构:

    • 主要用于整体视图。
    • 次要的,用于在整体视图中对内容或元素进行分组。
    • 第三级,用于将内容或元素分组到第二级元素中。

    要查看它们的实际效果,您现在将为应用添加背景色-这次使用情节提要。

    打开Main.storyboard。在Dark Arts场景中,将Table ViewTeacherCellBackground设置为System Background Color

    构建并运行以在亮和暗模式下查看效果。 如您所见,列表的背景颜色会根据外观自动更改,但是在Dark Mode下看不到文本。

    接下来,您将对其进行修复。

    2. Foreground Colors

    对于前景内容,例如label,还可以使用各种级别的语义颜色来传达内容的重要性。 分级颜色的示例包括.label,.secondaryLabel,.tertiaryLabel

    再次打开Main.storyboard。 然后在Dark Arts场景中,将Color Name Label设置为Label Color

    构建并运行。 在明暗模式下查看老师的名字。

    专业提示:您可以在亮和暗模式之间切换模拟器,而无需返回Xcode。 在模拟器中,选择Features ▸ Toggle Appearance — Shift-Command-A在它们之间进行切换。

    真好!只需进行少量更改,您的应用程序现在在支持黑暗模式方面将变得更加出色。

    但是,您可以拥有更多!


    Elevation

    Elevation是z轴上两层用户界面layers之间的距离。在light模式下,当用户界面的一层layer位于另一层之上时,开发人员可以使用阴影来增强深度感知。

    但这在Dark Mode下不起作用。虽然黑色阴影不够明显,但深色图层的较浅阴影看起来并不正确。

    为了解决此问题,暗模式使用两组背景颜色:基色和高色(base and elevated)。基色较暗,因此背景界面看起来已退去。相反,高色较浅,这使得前景界面看起来突出。

    您可以在Modal表中看到一个很好的示例,说明了这一概念。

    打开Main.storyboard。在Teacher Detail View Controller中,将根视图的Background设置为System Background Color。这与您在先前步骤中为列表背景设置的值完全相同。

    在这里时,请同时更改以下内容:

    • 首先,将“名称颜色”设置为Label Color
    • 其次,将Taught at HogwartsColor设置为Tertiary Label Color
    • 第三,将Years at HogwartsColor设置为Secondary Label Color

    构建并运行。 点击一行以查看详细信息屏幕。

    查看后面view controller的背景色。以及在前面的详细信息屏幕的背景色。尽管将它们都设置为相同的.systemBackgroundColor,但它们看起来却有所不同。在黑暗模式下更明显。

    请记住,应用程序中的列表在黑暗模式下具有.systemBackgroundColor的纯黑色背景。但是在详细信息屏幕中,当以模态形式显示在其父级顶部时,它具有深灰色的背景色。此行为是正常现象,无需任何额外努力即可提供给您。

    黑暗模式是动态的。这意味着,当界面(如popover or modal sheet)位于前景中时,背景颜色会自动从base变为elevated


    Dynamic Colors

    这些新引入的系统颜色和语义颜色很有用,但并非在所有情况下都有效。例如,如果您需要使用品牌颜色或设计要求使用Apple提供的颜色以外的颜色,它们将对您没有帮助。

    在使用Dark Mode之前,您可以通过多种方式合并自定义颜色。使用UIColor初始化程序时,开发人员经常使用代码或Asset Catalogs。幸运的是,Apple进行了更新,将暗模式考虑在内。

    您将首先解决编码方法。

    1. UITraitCollection

    但是,在继续之前,您首先需要了解UITraitCollection的概念。

    iOS通过UITraitEnvironment协议的traitCollection属性公开了任何应用程序的界面环境。 UIWindowUIViewControllerUIView都是符合此协议的类。

    您可以在iOS应用中访问许多用户界面特征,例如尺寸类别,强制触摸功能和样式。 通过考虑这些属性和相关方法,可以使用户界面适应系统的建议。

    黑暗模式是由trait collections的魔法处理的。 这是一个新特性,接下来您将学习如何使用它。

    2. UIColor Dynamic Provider

    要在代码中构造颜色,您将使用基于闭包的初始化程序。

    打开TeacherDetailViewController.swift。 替换viewDidLoad()中的这一行代码:

    headerBackgroundView.backgroundColor = .white
    

    用下面的:

    headerBackgroundView.backgroundColor =
      // 1
      UIColor { traitCollection in
        // 2
        switch traitCollection.userInterfaceStyle {
        case .dark:
          // 3
          return UIColor(white: 0.3, alpha: 1.0)
        default:
          // 4
          return UIColor(white: 0.7, alpha: 1.0)
        }
      }
    

    这是一个细分:

    • 1) 您调用新的UIColor初始化程序,该初始化程序使用单个输入UITraitCollection类型进行的闭包。 iOS会调用此块,并根据应用的用户界面样式为您提供特定的颜色。 如果用户更改了系统界面样式,则将自动再次调用该回调,并将相应地更改颜色。
    • 2) 您打开traitCollectionuserInterfaceStyle属性以了解应用程序处于哪种外观模式。
    • 3) 如果应用程序处于Dark Mode,它将返回更深的灰色阴影。
    • 4) 如果应用程序不在Dark Mode下,它将返回较浅的灰色阴影。

    构建并运行。 点击一行以查看详细信息屏幕的标题。 然后切换到暗模式并查看反应的变化。

    如果您不想在Interface Builder中使用颜色,则可以在代码中创建颜色。 如果您计划使用Interface Builder,则需要Asset Catalog

    3. Asset Catalog

    iOS 11开始,您可以将颜色保存在Asset Catalogs中,并在代码和Interface Builder中使用它们。 您可以通过简单的调整使颜色动态。

    打开Assets.xcassets并查看colors文件夹。 在属性检查器的新Appearances部分下,您可以添加颜色的变体。 最简单的选择是Any, Dark,您可以在其中为深色外观提供新的颜色。 对于colors,您会发现一种动态颜色,称为thumbnail-border。 对于黑暗模式,它提供绿色;对于明亮模式,它提供灰色。

    您问在哪里使用这种颜色? 您很快就会看到。

    打开Main.storyboard。 在Dark Arts场景中,有一个Border View,它充当教师头像上的stroke。 当前,其Background设置为静态颜色:rw-dark。 由于您不会留下最小的细节,因此请将其更改为thumbnail-border

    现在,构建并运行。 了解教师在黑暗模式下如何pop更多。


    Dynamic Images

    您可能已经在详细信息页面的底部注意到了一幅精美的霍格沃茨画作。 如果应用程序处于黑暗模式时在夜间显示霍格沃茨,那会不会很酷?

    好消息! 您可以使用dynamic images来做到这一点。

    遵循用于在图像的Assets.xcassets中向颜色添加变体的相同过程。

    打开Assets.xcassets。 您会看到两张名为霍格沃茨hogwarts和霍格沃茨之夜hogwarts-night的图像。 单击霍格沃茨hogwarts

    在“属性”检查器中,单击Appearances,然后选择Any, Dark。 出现一个新的slot

    右键单击hogwarts-night,然后单击Show in Finder。 将图像从Finder拖到您在霍格沃茨中创建的空白位置slot。 现在删除hogwarts-night,因为两个图像的名称都为hogwarts

    构建并运行。 享受霍格沃茨的美丽月光,但远离Lupin

    1. SFSymbols

    苹果公司为iOS 13推出的最酷的功能之一是SFSympols,这是一整套的一致且高度可配置的图像。 这些符号根据外观,大小和重量可以很好地缩放。 最重要的是,您还可以在应用程序中免费使用它们。

    他们还准备好黑暗模式。 您可以将它们着色为任何动态颜色,并且它们的适应效果很好。 除非您的应用程序需要特定的图像和资源,否则SFSymbols可以满足您的插图需求。

    是时候使用SFSymbols在房屋名称旁边添加房屋图标,向详细信息屏幕添加一些元素了。

    打开TeacherDetailViewController.swift。 在viewDidLoad()的最后一行,添加:

    houseImageView.image = UIImage(systemName: "house.fill")
    

    这行代码使用了新的UIImage初始化程序,该初始化程序使用SFSymbols目录中的符号名称。

    构建并运行。 看到漂亮的小房子图标。 它不像霍格沃茨的公共休息室那么漂亮,但是它可以完成工作。

    房子在明亮模式下很漂亮,但它却是黑色的,在黑暗模式下很难看清。 您知道如何解决该问题!

    在您刚刚插入的行上方,有一段代码设置了houseImageViewtintColor

    houseImageView.tintColor = .black
    

    替换为

    houseImageView.tintColor = houseLabel.textColor
    

    此行将houseImageViewtintColor设置为houseLabeltextColor。 请记住,您为该label使用了系统颜色,因此它可以动态适应设备外观。

    构建并运行。 切换外观模式时,现在看到主页图标会切换颜色。

    想知道这是怎么发生的? 这是SFSymbols的魔力。 请记住,它们可以很好地扩展并适应您的需求。 您可以根据需要使用任何大小或颜色的它们。

    注意:AppleSFSymbols提供了配套的Mac应用程序。 您可以在此处here下载并浏览目录。 您在UIColor的初始值设定项中使用的字符串名称来自此应用程序。


    Opting Out of Dark Mode

    黑暗模式比以往更受欢迎。您可以在全系统范围内将设备设置为暗模式,现在所有Apple和许多第三方应用程序都将其包括在内。虽然您可以选择退出黑暗模式,但对于喜欢在黑暗中进行所有操作的用户而言,可能会造成眼睛疲劳。我们非常鼓励您在选择不支持黑暗模式之前重新考虑。

    但是,如果您确定要退出暗模式,则可以选择以下几种方法:

    • 1) 通过使用Info.plist中的UIUserInterfaceStyle键为整个应用程序关闭暗模式。
    • 2) 在应用程序的UIWindow上设置界面样式,这通常意味着整个应用程序。
    • 3) 设置特定UIViewUIViewController的界面样式。

    您将为应用程序一一设置。

    注意:由于最终项目违反了本教程的目的,因此最终项目将保持黑暗状态。另外,在浏览下面的每个选项时,请记住在尝试新方法之前删除用于退出暗模式的代码。

    1. Opting Out with Info.plist

    打开Info.plist。然后添加一个名为UIUserInterfaceStyle的键并将其设置为Light

    构建并运行该应用程序。一切都像在黑暗模式下什么也没做一样。

    在继续下一步之前,请记住要删除上述key

    2. Opting Out in UIWindow

    打开SceneDelegate.swift。 替换:

    var window: UIWindow?
    

    var window: UIWindow? {
      didSet {
        window?.overrideUserInterfaceStyle = .light
      }
    }
    

    由于此应用使用storyboards,因此系统会设置window

    此代码块设置Swift属性观察器观察window。 一旦设置了此属性,就可以将界面样式覆盖为.light。 由于此应用程序仅使用一个窗口,因此覆盖窗口上的样式会使该应用程序像在Info.plist中设置该键一样起作用。

    构建并运行以确认。

    在继续下一步之前,请记住删除上面的代码。

    3. Opting Out in UIViewController

    打开TeacherDetailViewController.swift。 您将使该视图控制器成为不遵守黑暗模式的叛逆者。

    viewDidLoad()中,在对super.viewDidLoad()的调用之后,立即插入:

    overrideUserInterfaceStyle = .light
    

    该行覆盖此特定视图控制器的样式。

    构建并运行。 看看黑暗模式! 列表页面为深色,而详细信息页面为浅。

    后记

    本篇主要讲述了支持DarkMode的简单实用示例,感兴趣的给个赞或者关注~~~

    相关文章

      网友评论

          本文标题:UIKit框架(四十五) —— 支持DarkMode的简单示例(

          本文链接:https://www.haomeiwen.com/subject/htohlktx.html