WWDC 23 大家的目光都被 visionOS 吸引了,作为 UIKit 开发者关注一下现在今年的 What’s New in UIKit session 实为必要。虽然今年更新的内容似乎并没有那么吸引人。

笔者参照官方给出的代码片段复现了一些简略页面完结,而且将代码整合到仓库WhatsNewInUIKit,希望能够协助你更快上手和了解这些新特性。笔者还按照事务了解和适配进度的优先级,对 session 内容进行了从头排序和收拾。

总的来说,今年的更新主要包含以下几个方面:

  • 开发体会
  • 通用组件
  • 国际化
  • iPadOS 适配

2022年笔者在云音乐组内和博客分享了 WWDC22 UIKit 新功用,有兴趣能够先回忆一下这篇文章,这个系列会一向坚持更新。

开发体会

预览

新版别的 Xcode 中新增了 #Preview()这个宏,总算,在用户界面开发上 UIKit 也能够获得和 SwiftUI 一样的预览体会了。

开发者应该知道的 UIKit 新变化 | WWDC23

开发者能够自界说预览的视图的称号,下面的 Demo 中运用了 #Preview()并指定预览的称号为 NumberVC

class NumberViewController: UIViewController {
    // ...
}
#Preview("NumberVC") {
    let controller = NumberViewController()
    return controller
}

除了快速预览 UIViewController ,开发者还能够在面板快速预览UIView及其子类。实际体会下来这项功用还是非常实用的,能够在一个面板上以调集的形式显示检查不同机型上的显示作用。

开发者应该知道的 UIKit 新变化 | WWDC23

开发者能够在一个代码文件下创建多个#Preview()宏,所有预览将展现在 Preview 页面的顶部很方便切换。这个宏的界说长得像这样,需求留意的是这个宏仅在新版别的 Xcode 和体系上收效。

@available(iOS 17.0, macOS 14.0, tvOS 17.0, *)
@freestanding(declaration) public macro Preview(_ name: String? = nil, traits: PreviewTrait<Preview.ViewTraits>..., body: @escaping () -> UIViewController) = #externalMacro(module: "PreviewsMacros", type: "Common")

至于 Preview 完结的原理能够移步这篇文章检查。

viewIsAppearing

viewIsAppearing的触发机遇能够让开发者更方便的对用户界面改写进行操作,关于这个生命周期你需求知道的有以下几点:

  • 向前兼容到 iOS 13,不少运用的最低 target 在今年都有机会升级到这个版别

  • viewIsAppearing只会触发一次,不会像layoutSubviews那样被多次调用

  • 机遇介于viewWillAppearviewDidAppear之间,在view transition 之前

    开发者应该知道的 UIKit 新变化 | WWDC23

  • viewWillAppearviewDidAppear适用于不依赖视图的结对调用,例如注册数据库通知以及销毁注册

    开发者应该知道的 UIKit 新变化 | WWDC23

SF Symbols 动画

之前听《Anyway.FM》播客主播有说到 SF Symbols 或许是 Apple 在规划界做出的最大奉献,今年的 SF Symbols 5 带来了通用动画这一重要更新,对独立开发来说又是一大利好。

动画的形式能够大体分为两种,一种是单次动画,一种是继续动画,作用也供给了多种挑选。

// 单次 Bounce 动画
imageView.addSymbolEffect(.bounce)

开发者应该知道的 UIKit 新变化 | WWDC23

// 单次 Pulse 动画
imageView.addSymbolEffect(.pulse)

开发者应该知道的 UIKit 新变化 | WWDC23

// 单次缩放动画
imageView.addSymbolEffect(.scale)

开发者应该知道的 UIKit 新变化 | WWDC23

// 继续可变渐变动画
imageView.addSymbolEffect(.variableColor.iterative)
imageView.removeSymbolEffect(ofType:.variableColor)

开发者应该知道的 UIKit 新变化 | WWDC23

// 符号切换动画
imageView.setSymbolImage(UIImage(systemName: "swift")!, contentTransition: .replace.offUp)

开发者应该知道的 UIKit 新变化 | WWDC23

SF Symbols 为跨 UI 结构供给了统一 API,为自界说符号供给了复合层注解。假如你对新增的功用感兴趣能够观看这个session,上述的几种动画用例代码都能够WhatsNewInUIKit中找到。

Trait System

假如你没有触摸过全局款式开发,或许会对 Trait 这套结构感到陌生。

开发者应该知道的 UIKit 新变化 | WWDC23

UITraitCollection 包含许多体系特征,例如用户界面款式(切换日间/夜间主题)、水平缓笔直尺寸(横屏/竖屏布局)等等。

开发者应该知道的 UIKit 新变化 | WWDC23

依据Unleash the UIKit trait system的说法,有两点需求开发者留意:

  • View controllers 从其 view 的 superview 承继trait collection,而不是直接从其parent view controller承继。

  • 假如在 view 增加到 hierarchy 之前拜访 view controller 的 trait collection,那么 view controller 将获取不到最新的traits,导致viewWillAppear 受到影响(需求适配 viewIsAppearing)。

除此之外,session还提及了以下几点更新:

  • 开发者答应编写自界说的 traits,而且选用了更灵敏的 API。

    开发者应该知道的 UIKit 新变化 | WWDC23

  • 选用注册的办法处理 traits,在 traits 发生更改时接收回调而不需求在子类中重写 traitCollectionDidChange(事实上已经被traitCollectionDidChange被标记为废弃)。以下列举了两种注册办法。

    开发者应该知道的 UIKit 新变化 | WWDC23
    开发者应该知道的 UIKit 新变化 | WWDC23

  • 答应将自界说 UIKit traits 与自界说 SwiftUI environment keys 相桥接,答应运用在 UIKit 和 SwiftUI 组件之间双向无缝传递 traits。

    开发者应该知道的 UIKit 新变化 | WWDC23
    开发者应该知道的 UIKit 新变化 | WWDC23

通用组件增强

UIPageControlTimerProgress

UIPageControlTimerProgress 有一个内置计时器能够轻松装备每个页面的继续展现时刻,当定时器抵达指定时刻时 UIPageControl 将主动翻滚页面。

开发者应该知道的 UIKit 新变化 | WWDC23

关于需求跟从视频播放器或外部计时器的页面,需求运用 UIPageControlProgress 跟着内容进度手动更新 currentProgress

开发者应该知道的 UIKit 新变化 | WWDC23

需求留意的是,用户需求在点击UIPageControl之后才干激活倒计时进度条。,WhatsNewInUIKit 包含了以下 Demo 能够方便快速上手这个新特性。

开发者应该知道的 UIKit 新变化 | WWDC23

UIContentUnavailableConfiguration

在事务开发过程中,针对无网络状况、搜索不命中状况、无内容状况都应该展现空态视图。在内容构成上该视图通常会包含一个一级文本、一个二级文本以及一个图片。自界说完结上有不同的办法,例如画一个视图然后增加自界说分类。

开发者应该知道的 UIKit 新变化 | WWDC23

新增的UIContentUnavailableConfiguration运用办法很容易了解,UIViewController 的拓展中包含了一个contentUnavailableConfiguration特点,更新 viewController 最佳办法是重写updateContentUnavailableConfiguration(using: state)

在 SwiftUI 中运用这个特性也很简略,运用UIHostingConfiguration 能完结空状况视图。

开发者应该知道的 UIKit 新变化 | WWDC23

例如在搜索场景中,能够运用如下代码在没有成果匹配的情况下展现空态界面。

    // Represent no search results empty state
    override func updateContentUnavailableConfiguration(using state: UIContentUnavailableConfigurationState) {
        var config: UIContentUnavailableConfiguration?
        if searchResults.isEmpty {
            config = .search()
        }
        contentUnavailableConfiguration = config
    }
    // Update search results for query
    searchResults = backingStore.results(for: query)
    setNeedsUpdateContentUnavailableConfiguration()

默认供给了UIContentUnavailableConfiguration.empty()UIContentUnavailableConfiguration.loading()UIContentUnavailableConfiguration.search()这几种完结,能够自界说的特点包含以下多项,经过苹果供给的空态 API, 开发者也能够审视自己之前完结相似需求时考虑是否周全。

    public var image: UIImage?
    public var imageProperties: UIContentUnavailableConfiguration.ImageProperties
    public var text: String?
    public var attributedText: NSAttributedString?
    public var textProperties: UIContentUnavailableConfiguration.TextProperties
    public var secondaryText: String?
    public var secondaryAttributedText: NSAttributedString?
    public var secondaryTextProperties: UIContentUnavailableConfiguration.TextProperties
    public var button: UIButton.Configuration
    public var buttonProperties: UIContentUnavailableConfiguration.ButtonProperties
    public var secondaryButton: UIButton.Configuration
    public var secondaryButtonProperties: UIContentUnavailableConfiguration.ButtonProperties
    public var alignment: UIContentUnavailableConfiguration.Alignment
    public var axesPreservingSuperviewLayoutMargins: UIAxis
    public var directionalLayoutMargins: NSDirectionalEdgeInsets
    public var imageToTextPadding: CGFloat
    public var textToSecondaryTextPadding: CGFloat
    public var textToButtonPadding: CGFloat
    public var buttonToSecondaryButtonPadding: CGFloat
    public var background: UIBackgroundConfiguration

调色盘菜单

调色板菜单(Palette Menus) 可了解成一排菜单构成的 stackView,通常用于在一系列选项中挑选,现在它作为一个新的控件被运用。

要将任何菜单变成调色板菜单,只需在UIMenu目标的options:[]中增加.displayAsPalette

开发者应该知道的 UIKit 新变化 | WWDC23

假如你对调色板菜单的运用办法感兴趣,除了参阅仓库里完结的 Demo,还能够参阅这一篇文章Create Menus with Palette Picker in SwiftUI and UIKit。

UIStatusBarStyle

之前在开发过程中经常要依据页面背景色彩重写指定状况栏风格,iOS 中默认状况栏款式会依据状况栏背景展现的内容动态调整明暗款式,甚至状况栏左边和右边的明暗款式都能够不同。

开发者应该知道的 UIKit 新变化 | WWDC23

这项更新意味着在 iOS 17 之后能够将原先自界说的状况栏代码删除。

国际化言语优化

按区域设置检索 UIImage

UIImageconfiguration中指定locale能够获得对应图画特定的变体,这为全球的用户营造一种归属感。

下面的比如中供给一个带有日语locale设置的configuration来获取该符号的日语版别。

开发者应该知道的 UIKit 新变化 | WWDC23

笔者简略完结了一个完结随机获取不同locale下的UIImage的Demo能够尝试玩一下。

开发者应该知道的 UIKit 新变化 | WWDC23

动态行高调整

部分言语字体往往需求比拉丁字母更多的笔直空间从而导致重叠和裁切的问题,如阿拉伯语、印地语和泰语等。

开发者应该知道的 UIKit 新变化 | WWDC23

新增的动态行高调整功用使得能够动态调整文本的控件(如 UILabel)主动调整行高和笔直距离来完结最佳的可读作用。

需求留意的是,假如开发者手动设定了UIFont则或许导致这项功用不再适用,苹果引荐运用UIFontTextStyle来设置字体。

开发者应该知道的 UIKit 新变化 | WWDC23

iPadOS 适配改进

Apple 在 iPadOS 适配上也下了不少功夫,由于本人对这部分事务触摸比较少,假如你对这此感兴趣引荐你观看视频 session 了解更新的全部内容,以下简略列举了几个更新。

窗口拖拽交互

用户能够在 UINavigationBar 的任何方位拖动以移动窗口.

开发者应该知道的 UIKit 新变化 | WWDC23

侧边栏调整

运用双列或三列款式创建的 UISplitViewController 的主动翻开/关闭侧边栏的行为形式获得了更新。

开发者应该知道的 UIKit 新变化 | WWDC23

键盘滑动支撑

键盘上的 Page Up、Page Down、Home 和 End 键能够触发 UIScrollView 翻滚,开发者能够指定 allowsKeyboardScrolling 确认是否禁用此行为。

Apple Pencil 笔迹

PencilKit引入了新的墨迹类型。

开发者应该知道的 UIKit 新变化 | WWDC23

结束语

除了以上提及的功用之外视频还介绍了不少其他特性:

  • UICollectionView 在 diffable data source 和 snapshot 方面性能大幅提升
  • Compositional Layout 引入了 uniformAcrossSiblings 布局
  • 新的 Spring 动画参数仅需求durationbounce两个参数
  • 文本交互上更新了光标、挑选器以及自界说交互菜单
  • 支撑将文件或内容直接拖放到运用图标上直接翻开相应的运用与内容
  • UIImageViewUIGraphicsImageRenderer加入了对ISO HDR图画的支撑

假如这篇文章对你有协助,别忘了在 GitHub 上为 WhatsNewInUIKit 点一个。

作为开发者,一同尝试兼容 app 到 iOS 17,适配新的API,探究新的事务或许性吧。

参阅链接

  • WWDC 2023: What’s New In UIKit | Apple
  • What’s new in UIKit | WWDC NOTES
  • WWDC 2023: What’s New In UIKit | Steven Curtis
  • WWDC23 10055 – UIKit 中的新功用|老司机技术
  • Create Menus with Palette Picker in SwiftUI and UIKit|SwiftyLion