WWDC Quick Look 💓 By SwiftGGTeam
Build a UIKit app with the new design

Build a UIKit app with the new design

观看原视频

Highlight

全面拆解 iOS 26 新设计在 UIKit 层面的适配方案,覆盖 Tab、导航栏、Presentation、搜索、控件、自定义 Glass 六个领域。


核心内容

旧应用重新编译到 iOS 26 SDK,立刻就能看到 Tab Bar 浮起来、导航栏变透明、按钮长出 Liquid Glass 背景。问题是接下来怎么办——以前为了”统一观感”加的 UIBarAppearancebackgroundColor、自定义按钮配色,现在反而会盖住玻璃效果。Sanaa(UIKit 团队工程师)在这一节用了快 25 分钟,把六个领域里需要重新理解的细节讲了一遍。

整段视频的主线是:UIKit 把 Tab Bar、Split View、Navigation Bar、Toolbar、Presentation、Search Bar、Slider/Switch 等组件都重做了一遍材质和布局,开发者要做的是删掉旧的自定义代码,再用新的 API 配置那些自动行为搞不定的细节。例如 Tab Bar 滚动最小化只要一行 tabBarMinimizeBehavior,Sidebar 下方的艺术图延伸用 UIBackgroundExtensionView,弹窗变形过渡靠 preferredTransition = .zoom,自定义玻璃则交给 UIGlassEffectUIVisualEffectView。每个 API 都对应一个具体场景,没有”灵活性”这种空话。


详细内容

Tab Bar 与底部 Accessory02:31 起)

// Minimize tab bar on scroll
tabBarController.tabBarMinimizeBehavior = .onScrollDown

// Add a bottom accessory
let nowPlayingView = NowPlayingView()
let accessory = UITabAccessory(contentView: nowPlayingView)
tabBarController.bottomAccessory = accessory

关键点:

  • tabBarMinimizeBehavior = .onScrollDown:向下滚动隐藏 Tab Bar,反向滚动恢复,焦点留给内容。
  • UITabAccessory:用于在 Tab Bar 上方挂一个辅助视图,比如音乐 App 的 Mini Player。
  • 当 Tab Bar 最小化时,bottomAccessory 会动画收进 Tab Bar 内联展示,剩余空间变小。

辅助视图自适应(03:35):

// Update the accessory with the trait
registerForTraitChanges([UITraitTabAccessoryEnvironment.self]) { (view: MiniPlayerView, _) in
    let isInline = view.traitCollection.tabAccessoryEnvironment == .inline
    view.updatePlayerAppearance(inline: isInline)
}

// Automatic trait tracking with updateProperties()
override func updateProperties() {
    super.updateProperties()
    let isInline = traitCollection.tabAccessoryEnvironment == .inline
    updatePlayerAppearance(inline: isInline)
}

关键点:

  • 通过 UITraitTabAccessoryEnvironment trait 监听 inline / 独立两种状态。
  • inline 时空间紧张,要主动隐藏次要控件(音乐 App 隐藏部分播放控件)。
  • updateProperties() 是 WWDC25 引入的自动 trait 追踪入口,详见 “What’s new in UIKit”。

Sidebar 下方的艺术图延伸05:51

// Extend content underneath the sidebar
let posterImageView = UIImageView(image: ...)

let extensionView = UIBackgroundExtensionView()
extensionView.contentView = posterImageView
view.addSubview(extensionView)

let detailsView = ShowDetailsView()
view.addSubview(detailsView)

关键点:

  • UIBackgroundExtensionView 把内容视图(如海报)填充到 safe area 之外的空间。
  • 默认按 safe area 自动延伸:顶部留给状态栏/导航栏,前缘留给 Sidebar。
  • 不希望被延伸的元素(剧名、剧集列表)作为 sibling 添加,不要塞进 extensionView 内部。

导航栏分组与文本字幕08:38 / 10:15

// Custom grouping
navigationItem.rightBarButtonItems = [
    doneButton,
    flagButton, folderButton, infoButton,
    .fixedSpace(0),
    shareButton, selectButton
]

// Titles and subtitles
navigationItem.title = "Inbox"
navigationItem.subtitle = "49 Unread"

关键点:

  • 系统按规则自动分组:图标按钮共享玻璃背景,文字按钮、Done/Close、prominent 风格独占背景。
  • .fixedSpace(0) 强制把同类按钮拆成两组——例子里把 Share 单独划出去。
  • navigationItem.subtitle 是 iOS 26 新增的 API,渲染在标题下方;largeSubtitleView 在大标题下方放可交互视图(如 Mail 的过滤按钮)。
  • 大标题改成跟随内容滚动,所以 scroll view 要完整延伸到导航栏下面。

Edge Effect 自定义容器11:20

// Edge effect's custom container
let interaction = UIScrollEdgeElementContainerInteraction()
interaction.scrollView = contentScrollView
interaction.edge = .bottom
buttonsContainerView.addInteraction(interaction)

关键点:

  • 滚动视图在导航栏/工具栏下方会自动加视觉处理(Scroll Edge Effect)。
  • 浮在边缘的自定义容器(比如悬浮按钮区)要用 UIScrollEdgeElementContainerInteraction 把 edge effect 接到容器后面,否则容器下方的文字会糊。

Zoom Transition 与 Action Sheet 锚点13:55

// Morph popover from its source button
viewController.popoverPresentationController?.sourceItem = barButtonItem

// Morph sheet from bar button
viewController.preferredTransition = .zoom { _ in
    folderBarButtonItem
}

// Setting source item for action sheets
alertController.popoverPresentationController?.sourceItem = barButtonItem

关键点:

  • sourceItem 指向源按钮,弹窗从按钮位置变形展开。
  • preferredTransition = .zoom { ... } 用于 sheet 风格的页面,按钮形态会融进新页面。
  • iPhone 上的 Action Sheet 现在也锚定到 source item,行为与 iPad 一致;没有 source 时居中显示并自动加取消按钮。

搜索栏放置15:36 / 17:03

// Place search bar in a toolbar
toolbarItems = [
    navigationItem.searchBarPlacementBarButtonItem,
    .flexibleSpace(),
    addButton
]

// Place search at the trailing edge of the navigation bar (iPad)
navigationItem.searchBarPlacementAllowsExternalIntegration = true

// Search as a dedicated view
navigationItem.preferredSearchBarPlacement = .integratedCentered

// Tab Bar search shortcut
searchTab.automaticallyActivatesSearch = true

关键点:

  • iPhone 上推荐让搜索栏移到 toolbar,使用 searchBarPlacementBarButtonItem
  • iPad 开 searchBarPlacementAllowsExternalIntegration 后,系统会在导航栏尾部摆搜索栏(macOS 风格)。
  • Tab Bar 上的 Search Tab 设 automaticallyActivatesSearch = true,点击直接展开成输入框。

控件:Glass Button、Slider、Switch17:52

// Standard glass
button.configuration = .glass()

// Prominent glass
tintedButton.configuration = .prominentGlass()

// Neutral slider with 5 ticks and a neutral value
slider.trackConfiguration = .init(allowsTickValuesOnly: true,
                                  neutralValue: 0.2,
                                  numberOfTicks: 5)

// Thumbless slider
slider.sliderStyle = .thumbless

关键点:

  • .glass() / .prominentGlass()UIButton.Configuration 的两个新工厂方法。
  • Slider 新增刻度模式(allowsTickValuesOnly)、中性锚点(neutralValue,例如照片调亮度的 0 点)和 .thumbless 无滑块样式。
  • Switch 和 Segmented Control 的拇指(thumb)会带 Liquid Glass 交互动效。

自定义 Glass:UIGlassEffect 与容器20:28 / 23:52

// Adopting glass for custom views
let effectView = UIVisualEffectView()
addSubview(effectView)

let glassEffect = UIGlassEffect()
glassEffect.tintColor = .systemBlue
glassEffect.isInteractive = true

UIView.animate {
    effectView.effect = glassEffect
}

// Adding glass elements to a container
let container = UIGlassContainerEffect()
let containerView = UIVisualEffectView(effect: container)

let view1 = UIVisualEffectView(effect: UIGlassEffect())
let view2 = UIVisualEffectView(effect: UIGlassEffect())
containerView.contentView.addSubview(view1)
containerView.contentView.addSubview(view2)

关键点:

  • UIGlassEffect 应用到 UIVisualEffectView 上,赋值时若包在 UIView.animate 里会触发 materialize 动画;置 nil 时是 dematerialize。
  • tintColor 给玻璃染色,isInteractive = true 启用按压时的弹性反馈。
  • UIGlassContainerEffect 把多个玻璃视图放进同一个容器,靠近时自动融合,移开时分离;spacing 控制融合距离阈值。
  • cornerConfiguration = .containerRelative() 让子视图的圆角随容器边距自动变化。

核心启发

1. 把”自动迁移”作为重做 UI 的第一步

为什么值得做:iOS 26 SDK 重新编译就能拿到大部分 Liquid Glass 效果,先看自动结果,再决定哪些地方需要手动调整,比闷头重写省一大半工作。

怎么开始:用新 SDK 编译现有 App,逐屏截图对比,把”自动变好”和”自动变糟”两类问题分开记录——前者直接收下,后者再开工。

2. 删掉旧的自定义 Bar 外观

为什么值得做:UIBarAppearancebackgroundColor、按钮配色等老代码会直接干扰 Glass 材质,不删就拿不到新设计。

怎么开始:搜索项目里所有 UIBarAppearance / setBackgroundImage / barTintColor,逐一评估能否移除;只保留信息表达必需的 tintColor + style = .prominent

3. 把 Sidebar 内容用 UIBackgroundExtensionView 重做

为什么值得做:iOS 26 上 Sidebar 看起来最好的状态是底下有内容延伸过去(参考 TV App),用 UIBackgroundExtensionView 一两行就能拿到这个效果。

怎么开始:找到 App 里包含 Sidebar 的详情页,把背景图(海报、封面、地图)包进 UIBackgroundExtensionView.contentView,剧名/标题/列表作为 sibling 添加;必要时关掉 automaticallyPlacesContentView 自定义布局。

4. 给所有自定义浮动容器加 ScrollEdgeElementContainerInteraction

为什么值得做:滚动视图边缘自动模糊处理只对系统 Bar 生效;自定义浮动按钮区如果没接入,下方文字会和按钮糊在一起。

怎么开始:列出所有 floating button cluster / quick-action bar,给它们的容器 view 加 UIScrollEdgeElementContainerInteraction,并设对应 scrollViewedge

5. 在合适场景里用 UIGlassEffect 包装自定义控件

为什么值得做:自家的播放控件、轨道选择器、徽章如果还在用纯色背景,会显得游离于系统视觉之外;UIGlassEffect + UIGlassContainerEffect 让它们融入 Liquid Glass 体系。

怎么开始:选一个最显眼的自定义浮窗作为试点,用 UIVisualEffectView 包裹,设 tintColorisInteractive,多元素则塞进 UIGlassContainerEffect 验证融合动效。


关联 Session

评论

GitHub Issues · utterances