uikit-expert
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseUIKit Expert Skill
UIKit专家技能
Overview
概述
Use this skill to build, review, or improve UIKit features with correct lifecycle management, performant Auto Layout, modern collection view APIs, and safe navigation patterns. Prioritize native APIs, Apple's documented best practices, and performance-conscious patterns. This skill focuses on facts and best practices without enforcing specific architectural patterns (no MVVM/VIPER/Coordinator mandates).
使用本技能构建、评审或优化UIKit功能,确保正确的生命周期管理、高性能的Auto Layout、现代集合视图API以及安全的导航模式。优先使用原生API、苹果官方文档推荐的最佳实践和注重性能的设计模式。本技能聚焦于事实与最佳实践,不强制特定架构模式(无MVVM/VIPER/Coordinator等要求)。
Workflow Decision Tree
工作流决策树
1) Review existing UIKit code
1) 评审现有UIKit代码
- Check view controller lifecycle usage — for geometry,
viewIsAppearingfor setup only (seeviewDidLoad)references/view-controller-lifecycle.md - Verify Auto Layout correctness — batch activation, no constraint churn, (see
translatesAutoresizingMaskIntoConstraints)references/auto-layout.md - Check collection/table view APIs — diffable data sources, stable identity, CellRegistration (see )
references/modern-collection-views.md - Verify cell configuration uses , not deprecated
UIContentConfiguration(seetextLabel)references/cell-configuration.md - Check list scroll performance — prefetching, cell reuse cleanup, reconfigureItems (see )
references/list-performance.md - Verify navigation patterns — bar appearance all 4 slots, no concurrent transition crashes (see )
references/navigation-patterns.md - Check animation correctness — API selection, PropertyAnimator state machine, constraint animation (see )
references/animation-patterns.md - Audit memory management — , delegate ownership, Timer/CADisplayLink traps (see
[weak self])references/memory-management.md - Check concurrency safety — Task lifecycle, cancellation in viewDidDisappear (see )
references/concurrency-main-thread.md - If SwiftUI interop present — verify UIHostingController containment, sizingOptions (see )
references/uikit-swiftui-interop.md - Check image loading — downsampling, cell reuse race condition (cancel/clear/verify) (see )
references/image-loading.md - Verify keyboard handling — UIKeyboardLayoutGuide over manual notifications (see )
references/keyboard-scroll.md - Check trait handling and accessibility — registerForTraitChanges, Dynamic Type, VoiceOver (see )
references/adaptive-appearance.md - Validate modern API adoption and iOS 26+ availability handling (see )
references/modern-uikit-apis.md
- 检查视图控制器生命周期的使用:几何相关操作使用,仅在
viewIsAppearing中执行初始化设置(详见viewDidLoad)references/view-controller-lifecycle.md - 验证Auto Layout的正确性:批量激活约束、避免约束频繁重建、正确设置(详见
translatesAutoresizingMaskIntoConstraints)references/auto-layout.md - 检查集合/表格视图API:使用差分数据源、稳定标识符、CellRegistration(详见)
references/modern-collection-views.md - 验证单元格配置使用,而非已废弃的
UIContentConfiguration(详见textLabel)references/cell-configuration.md - 检查列表滚动性能:预加载、单元格复用清理、使用(详见
reconfigureItems)references/list-performance.md - 验证导航模式:配置全部4个导航栏外观插槽、避免并发转场崩溃(详见)
references/navigation-patterns.md - 检查动画正确性:API选择、PropertyAnimator状态机、约束动画(详见)
references/animation-patterns.md - 审计内存管理:使用、委托所有权、Timer/CADisplayLink陷阱规避(详见
[weak self])references/memory-management.md - 检查并发安全性:Task生命周期管理、在中取消任务(详见
viewDidDisappear)references/concurrency-main-thread.md - 若存在SwiftUI互操作:验证UIHostingController的容器化、sizingOptions设置(详见)
references/uikit-swiftui-interop.md - 检查图片加载:降采样处理、单元格复用竞争条件(取消/清空/验证)(详见)
references/image-loading.md - 验证键盘处理:使用UIKeyboardLayoutGuide替代手动通知监听(详见)
references/keyboard-scroll.md - 检查特性处理与无障碍支持:注册、动态字体、VoiceOver(详见
traitChanges)references/adaptive-appearance.md - 验证现代API的采用以及iOS 26+兼容性处理(详见)
references/modern-uikit-apis.md
2) Improve existing UIKit code
2) 优化现有UIKit代码
- Replace geometry work in with
viewDidLoad(seeviewIsAppearing)references/view-controller-lifecycle.md - Eliminate constraint churn — create once, toggle or modify
isActive(see.constant)references/auto-layout.md - Migrate from legacy to diffable data sources (see
UITableViewDataSource)references/modern-collection-views.md - Replace deprecated /
textLabel/detailTextLabelwithimageView(seeUIContentConfiguration)references/cell-configuration.md - Replace with
reloadItemsfor in-place cell updates (seereconfigureItems)references/list-performance.md - Fix navigation bar appearance — set all 4 appearance slots, use not
navigationItem(seenavigationBar)references/navigation-patterns.md - Improve animations — use PropertyAnimator for gestures, correct constraint animation pattern (see )
references/animation-patterns.md - Fix retain cycles — add , cancel Tasks in
[weak self], use block-based Timer (seeviewDidDisappear)references/memory-management.md - Migrate GCD to Swift concurrency — replace with
DispatchQueue.main.async(seeTask)references/concurrency-main-thread.md - Suggest image downsampling when or full-resolution loading detected (as optional optimization, see
UIImage(data:))references/image-loading.md - Replace keyboard notification handling with (see
UIKeyboardLayoutGuide)references/keyboard-scroll.md - Replace with
traitCollectionDidChange(seeregisterForTraitChanges)references/adaptive-appearance.md - Adopt iOS 26 APIs where appropriate — Observation, updateProperties(), .flushUpdates (see )
references/modern-uikit-apis.md
- 将中的几何相关操作迁移至
viewDidLoad(详见viewIsAppearing)references/view-controller-lifecycle.md - 消除约束频繁重建:一次性创建约束,通过切换或修改
isActive来调整(详见.constant)references/auto-layout.md - 从旧版迁移至差分数据源(详见
UITableViewDataSource)references/modern-collection-views.md - 用替代已废弃的
UIContentConfiguration/textLabel/detailTextLabel(详见imageView)references/cell-configuration.md - 用替代
reconfigureItems实现单元格原地更新(详见reloadItems)references/list-performance.md - 修复导航栏外观问题:配置全部4个外观插槽,使用而非
navigationItem(详见navigationBar)references/navigation-patterns.md - 优化动画:为手势使用PropertyAnimator、采用正确的约束动画模式(详见)
references/animation-patterns.md - 修复循环引用:添加、在
[weak self]中取消Tasks、使用基于block的Timer(详见viewDidDisappear)references/memory-management.md - 将GCD迁移至Swift并发:用替代
Task(详见DispatchQueue.main.async)references/concurrency-main-thread.md - 当检测到使用或全分辨率加载时,建议对图片进行降采样(可选优化,详见
UIImage(data:))references/image-loading.md - 用替代键盘通知监听(详见
UIKeyboardLayoutGuide)references/keyboard-scroll.md - 用替代
registerForTraitChanges(详见traitCollectionDidChange)references/adaptive-appearance.md - 酌情采用iOS 26 API:Observation、updateProperties()、.flushUpdates(详见)
references/modern-uikit-apis.md
3) Implement new UIKit feature
3) 实现新UIKit功能
- Design data flow first: identify owned state, injected dependencies, and model layer
- Set up view controller lifecycle correctly — one-time setup in , geometry in
viewDidLoad(seeviewIsAppearing)references/view-controller-lifecycle.md - Build Auto Layout with batch activation and zero churn (see )
references/auto-layout.md - Use modern collection view stack: DiffableDataSource + CompositionalLayout + CellRegistration (see )
references/modern-collection-views.md - Configure cells with and
UIContentConfiguration(seeconfigurationUpdateHandler)references/cell-configuration.md - Implement prefetching and proper cell reuse cleanup for lists (see )
references/list-performance.md - Set up navigation with all 4 appearance slots and concurrent-transition guards (see )
references/navigation-patterns.md - Choose correct animation API for the use case (see )
references/animation-patterns.md - Use in escaping closures, cancel Tasks in lifecycle methods (see
[weak self])references/memory-management.md - Use correctly, store Task references (see
@MainActor)references/concurrency-main-thread.md - If embedding SwiftUI — use full child VC containment for UIHostingController (see )
references/uikit-swiftui-interop.md - Downsample images for display, handle cell reuse race condition (see )
references/image-loading.md - Use for keyboard handling (see
UIKeyboardLayoutGuide)references/keyboard-scroll.md - Support Dynamic Type, VoiceOver, dark mode from the start (see )
references/adaptive-appearance.md - Gate iOS 26+ features with and provide sensible fallbacks (see
#available)references/modern-uikit-apis.md
- 先设计数据流:确定自有状态、注入依赖和模型层
- 正确设置视图控制器生命周期:在中执行一次性初始化,几何相关操作在
viewDidLoad中完成(详见viewIsAppearing)references/view-controller-lifecycle.md - 构建Auto Layout时使用批量激活,避免约束频繁重建(详见)
references/auto-layout.md - 使用现代集合视图栈:DiffableDataSource + CompositionalLayout + CellRegistration(详见)
references/modern-collection-views.md - 用和
UIContentConfiguration配置单元格(详见configurationUpdateHandler)references/cell-configuration.md - 为列表实现预加载和正确的单元格复用清理逻辑(详见)
references/list-performance.md - 配置导航时设置全部4个外观插槽,并添加并发转场防护(详见)
references/navigation-patterns.md - 根据使用场景选择正确的动画API(详见)
references/animation-patterns.md - 在逃逸闭包中使用,在生命周期方法中取消Tasks(详见
[weak self])references/memory-management.md - 正确使用,存储Task引用(详见
@MainActor)references/concurrency-main-thread.md - 若嵌入SwiftUI:对UIHostingController使用完整的子VC容器化(详见)
references/uikit-swiftui-interop.md - 对显示用图片进行降采样,处理单元格复用竞争条件(详见)
references/image-loading.md - 使用处理键盘交互(详见
UIKeyboardLayoutGuide)references/keyboard-scroll.md - 从设计初期就支持动态字体、VoiceOver、深色模式(详见)
references/adaptive-appearance.md - 用对iOS 26+特性做版本隔离,并提供合理的降级方案(详见
#available)references/modern-uikit-apis.md
Core Guidelines
核心准则
View Controller Lifecycle
视图控制器生命周期
- Use for one-time setup: subviews, constraints, delegates — NOT geometry
viewDidLoad - Use (back-deployed iOS 13+) for geometry-dependent work, trait-based layout, scroll-to-item
viewIsAppearing - fires multiple times — use only for lightweight layer frame adjustments
viewDidLayoutSubviews - is limited to transition coordinator animations and balanced notification registration
viewWillAppear - Always call in every lifecycle override
super - Child VC containment: →
addChild→addSubview— in that exact orderdidMove(toParent:) - Verify deallocation with logging during development
deinit
- 仅用于一次性初始化:添加子视图、设置约束、委托配置 — 不处理几何相关操作
viewDidLoad - (iOS 13+向后兼容)用于几何依赖操作、基于特性的布局、滚动到指定项
viewIsAppearing - 会触发多次 — 仅用于轻量级的图层帧调整
viewDidLayoutSubviews - 仅用于转场协调器动画和对称的通知注册
viewWillAppear - 所有生命周期重写方法中必须调用
super - 子VC容器化步骤:→
addChild→addSubview— 严格遵循此顺序didMove(toParent:) - 开发阶段通过日志验证对象是否被正确释放
deinit
Auto Layout
Auto Layout
- Always set on programmatic views
translatesAutoresizingMaskIntoConstraints = false - Use — never individual
NSLayoutConstraint.activate([]).isActive = true - Create constraints once, toggle or modify
isActive— never remove and recreate.constant - Never change priority from/to (1000) at runtime — use 999
.required - Animate constraints: update constant → call inside animation block on superview
layoutIfNeeded() - iOS 26+: use option to simplify constraint animation
.flushUpdates - Avoid deeply nested UIStackViews in reusable cells
- 所有通过代码创建的视图必须设置
translatesAutoresizingMaskIntoConstraints = false - 使用— 绝不单独设置
NSLayoutConstraint.activate([]).isActive = true - 一次性创建约束,通过切换或修改
isActive调整布局 — 绝不删除后重建.constant - 运行时绝不改变优先级至/从(1000) — 使用999替代
.required - 约束动画:更新constant值 → 在动画块中调用父视图的
layoutIfNeeded() - iOS 26+:使用选项简化约束动画
.flushUpdates - 可复用单元格中避免深度嵌套的UIStackView
Collection Views & Data Sources
集合视图与数据源
- Use with stable identifiers (UUID/database ID, not full model structs)
UICollectionViewDiffableDataSource - Use for content updates,
reconfigureItemsonly when cell type changesreloadItems - Use for initial population (bypasses diffing)
applySnapshotUsingReloadData - Use for any non-trivial layout
UICollectionViewCompositionalLayout - Use — no string identifiers, no manual casting
UICollectionView.CellRegistration - Use for cell content and
UIContentConfigurationfor cell backgroundsUIBackgroundConfiguration - Use for state-driven styling (selection, highlight)
configurationUpdateHandler
- 使用并搭配稳定标识符(UUID/数据库ID,而非完整模型结构体)
UICollectionViewDiffableDataSource - 内容更新使用,仅在单元格类型改变时使用
reconfigureItemsreloadItems - 初始数据填充使用(跳过差分计算)
applySnapshotUsingReloadData - 任何非简单布局都使用
UICollectionViewCompositionalLayout - 使用— 无需字符串标识符,无需手动类型转换
UICollectionView.CellRegistration - 使用配置单元格内容,
UIContentConfiguration配置单元格背景UIBackgroundConfiguration - 使用处理状态驱动的样式(选中、高亮)
configurationUpdateHandler
Navigation
导航
- Configure all 4 slots (standard, scrollEdge, compact, compactScrollEdge)
UINavigationBarAppearance - Set appearance on (per-VC) in
navigationItem, not onviewDidLoadinnavigationBarviewWillAppear - Use for deep links — not sequential push calls
setViewControllers(_:animated:) - Guard against concurrent transitions — check before push/pop
transitionCoordinator - Set once on the bar; use
prefersLargeTitlesper VClargeTitleDisplayMode
- 配置全部4个插槽(standard、scrollEdge、compact、compactScrollEdge)
UINavigationBarAppearance - 在中为
viewDidLoad(每个VC独立)设置外观,而非在navigationItem中设置viewWillAppearnavigationBar - 深度链接使用— 不使用连续的push调用
setViewControllers(_:animated:) - 防护并发转场 — 执行push/pop前检查
transitionCoordinator - 在导航栏上一次性设置;每个VC单独设置
prefersLargeTitleslargeTitleDisplayMode
Animation
动画
- — simple one-shot animations; check
UIView.animatein completionfinished - — gesture-driven, interruptible; respect state machine (inactive → active → stopped)
UIViewPropertyAnimator - — layer-only properties (cornerRadius, shadow, 3D transforms); set model value first
CABasicAnimation - iOS 17+ spring API: aligns with SwiftUI
UIView.animate(springDuration:bounce:) - Constraint animation: flush layout → update constant → animate on superview
layoutIfNeeded()
- — 简单的一次性动画;在完成回调中检查
UIView.animate状态finished - — 手势驱动、可中断的动画;遵循状态机(inactive → active → stopped)
UIViewPropertyAnimator - — 仅图层属性(cornerRadius、阴影、3D变换);先设置模型值再添加动画
CABasicAnimation - iOS 17+弹簧API:与SwiftUI对齐
UIView.animate(springDuration:bounce:) - 约束动画:刷新布局 → 更新constant → 在动画块中调用
layoutIfNeeded()
Memory Management
内存管理
- Default to in all escaping closures
[weak self] - Timer: use block-based API with , invalidate in
[weak self]viewWillDisappear - CADisplayLink: use weak proxy pattern (no block-based API available)
- NotificationCenter: in closure, remove observer in
[weak self]deinit - Nested closures: re-capture in stored inner closures
[weak self] - Delegates: always with
weak var delegate: SomeDelegate?constraintAnyObject - Verify deallocation with — if never called, a retain cycle exists
deinit
- 所有逃逸闭包默认使用
[weak self] - Timer:使用基于block的API并搭配,在
[weak self]中失效viewWillDisappear - CADisplayLink:使用弱代理模式(无基于block的API)
- NotificationCenter:闭包中使用,在
[weak self]中移除观察者deinit - 嵌套闭包:在存储的内部闭包中重新捕获
[weak self] - 委托:始终声明为并添加
weak var delegate: SomeDelegate?约束AnyObject - 通过验证对象释放 — 若未调用则存在循环引用
deinit
Concurrency
并发
- is
UIViewController— all subclass methods are implicitly main-actor@MainActor - Store references, cancel in
Task— notviewDidDisappeardeinit - Check before UI updates after
Task.isCancelledawait - does NOT inherit actor isolation — explicit
Task.detachedneeded for UIMainActor.run - Never call from background — use
DispatchQueue.main.syncawait MainActor.run
- 默认是
UIViewController— 所有子类方法隐式运行在主线程@MainActor - 存储Task引用,在中取消 — 不在
viewDidDisappear中取消deinit - 后更新UI前检查
awaitTask.isCancelled - 不继承actor隔离 — UI操作需显式使用
Task.detachedMainActor.run - 绝不能从后台线程调用— 使用
DispatchQueue.main.sync替代await MainActor.run
UIKit–SwiftUI Interop
UIKit–SwiftUI互操作
- UIHostingController: full child VC containment (→
addChild→addSubview), retain as stored propertydidMove - (iOS 16+) for Auto Layout containers
sizingOptions = .intrinsicContentSize - UIViewRepresentable: set mutable state in , not
updateUIView; guard against update loopsmakeUIView - UIHostingConfiguration (iOS 16+) for SwiftUI content in collection view cells
- UIHostingController:使用完整的子VC容器化(→
addChild→addSubview),并作为存储属性持有didMove - iOS 16+:Auto Layout容器中设置
sizingOptions = .intrinsicContentSize - UIViewRepresentable:在中修改可变状态,而非
updateUIView;防止更新循环makeUIView - iOS 16+:使用UIHostingConfiguration在集合视图单元格中嵌入SwiftUI内容
Image Loading
图片加载
- Decoded bitmap size = width × height × 4 bytes (a 12MP photo = ~48MB RAM)
- Downsample with ImageIO at display size — never load full bitmap and resize
- iOS 15+: use or
byPreparingThumbnail(of:)for async decodingprepareForDisplay() - Cell reuse: cancel Task in , clear image, verify identity on completion
prepareForReuse
- 解码后的位图大小 = 宽 × 高 × 4字节(一张12MP照片约占48MB内存)
- 使用ImageIO按显示尺寸降采样 — 绝不加载完整位图后再缩放
- iOS 15+:使用或
byPreparingThumbnail(of:)进行异步解码prepareForDisplay() - 单元格复用:在中取消Task、清空图片、完成时验证身份
prepareForReuse
Keyboard & Scroll
键盘与滚动
- Use (iOS 15+) — pin content bottom to
UIKeyboardLayoutGuideview.keyboardLayoutGuide.topAnchor - iPad: set for floating keyboards
followsUndockedKeyboard = true - Replace all manual keyboard notification handling with the layout guide
- 使用(iOS 15+) — 将内容底部固定到
UIKeyboardLayoutGuideview.keyboardLayoutGuide.topAnchor - iPad:为浮动键盘设置
followsUndockedKeyboard = true - 用布局向导替代所有手动键盘通知监听
Adaptive Layout & Accessibility
自适应布局与无障碍支持
- Use (iOS 17+) instead of deprecated
registerForTraitChangestraitCollectionDidChange - Dynamic Type: +
UIFont.preferredFont(forTextStyle:)adjustsFontForContentSizeCategory = true - Dark mode: use semantic colors (,
.label); re-resolve CGColor on trait changes.systemBackground - VoiceOver: set ,
accessibilityLabel,accessibilityTraitson custom viewsaccessibilityHint - Use for complex list item actions
UIAccessibilityCustomAction
- 使用(iOS 17+)替代已废弃的
registerForTraitChangestraitCollectionDidChange - 动态字体:使用+
UIFont.preferredFont(forTextStyle:)adjustsFontForContentSizeCategory = true - 深色模式:使用语义化颜色(、
.label);特性变化时重新解析CGColor.systemBackground - VoiceOver:为自定义视图设置、
accessibilityLabel、accessibilityTraitsaccessibilityHint - 复杂列表项操作使用
UIAccessibilityCustomAction
Quick Reference
速查参考
View Controller Lifecycle Method Selection
视图控制器生命周期方法选择
| Method | Use For |
|---|---|
| One-time setup: subviews, constraints, delegates |
| Geometry-dependent work, trait-based layout, scroll-to-item |
| Transition coordinator animations only |
| Lightweight layer frame adjustments (fires multiple times) |
| Start animations, analytics, post-appearance work |
| Cancel tasks, invalidate timers, save state |
| Final cleanup, cancel background work |
| 方法 | 适用场景 |
|---|---|
| 一次性初始化:添加子视图、设置约束、委托配置 |
| 几何依赖操作、基于特性的布局、滚动到指定项 |
| 仅用于转场协调器动画 |
| 轻量级图层帧调整(会触发多次) |
| 启动动画、统计上报、转场后操作 |
| 取消任务、失效Timer、保存状态 |
| 最终清理、取消后台任务 |
Animation API Selection
动画API选择
| API | Best For | Interactive | Off Main Thread |
|---|---|---|---|
| Simple one-shot changes | No | No |
| Gesture-driven, interruptible | Yes | No |
| Layer properties, 3D transforms | Limited | Yes (Render Server) |
| API | 最佳适用场景 | 可交互 | 后台线程执行 |
|---|---|---|---|
| 简单的一次性变化 | 否 | 否 |
| 手势驱动、可中断动画 | 是 | 否 |
| 图层属性、3D变换 | 有限支持 | 是(渲染服务器) |
Deprecated → Modern API Replacements
废弃API → 现代API替代
| Deprecated / Legacy | Modern Replacement | Since |
|---|---|---|
| | iOS 17 |
| Keyboard notifications | | iOS 15 |
| | iOS 14 |
| | iOS 14 |
| | iOS 15 |
| | iOS 13 |
| | iOS 13 |
Manual | | iOS 26 |
| Legacy app lifecycle | | Mandatory iOS 26 |
| | iOS 18 |
| 废弃/旧版API | 现代替代方案 | 最低iOS版本 |
|---|---|---|
| | iOS 17 |
| 键盘通知 | | iOS 15 |
| | iOS 14 |
| | iOS 14 |
快照更新使用 | | iOS 15 |
| | iOS 13 |
复杂布局使用 | | iOS 13 |
动画中手动调用 | | iOS 26 |
| 旧版应用生命周期 | | iOS 26强制要求 |
| | iOS 18 |
Review Checklist
评审检查清单
View Controller Lifecycle
视图控制器生命周期
- contains NO geometry-dependent work
viewDidLoad - Geometry/trait work is in , not
viewIsAppearingviewWillAppear - Every lifecycle override calls
super - Child VC uses correct containment sequence
- is implemented for leak verification during development
deinit
- 中无几何依赖操作
viewDidLoad - 几何/特性相关操作在中,而非
viewIsAppearingviewWillAppear - 所有生命周期重写方法都调用了
super - 子VC使用正确的容器化顺序
- 开发阶段实现用于泄漏验证
deinit
Auto Layout
Auto Layout
- on all programmatic views
translatesAutoresizingMaskIntoConstraints = false - Constraints activated via
NSLayoutConstraint.activate([]) - No constraint removal/recreation — using toggle or
isActivemodification.constant - No priority changes from/to (1000) at runtime
.required - No inside
setNeedsLayout()orlayoutSubviews(infinite loop)viewDidLayoutSubviews - Constraint identifiers set for debugging
- 所有代码创建的视图都设置了
translatesAutoresizingMaskIntoConstraints = false - 通过激活约束
NSLayoutConstraint.activate([]) - 无约束删除/重建 — 使用切换或
isActive修改.constant - 运行时无优先级至/从(1000)的变更
.required - 或
layoutSubviews中无viewDidLayoutSubviews(避免无限循环)setNeedsLayout() - 约束设置了标识符用于调试
Collection Views
集合视图
- Using diffable data source with stable identifiers (not full model structs)
- for content updates, not
reconfigureItemsreloadItems - instead of string-based register/dequeue
CellRegistration - instead of deprecated cell properties
UIContentConfiguration - No duplicate identifiers in snapshot (crash)
BUG_IN_CLIENT - Self-sizing cells have unambiguous top-to-bottom constraint chain
- 使用差分数据源并搭配稳定标识符(非完整模型结构体)
- 内容更新使用,而非
reconfigureItemsreloadItems - 使用替代字符串式的注册/复用
CellRegistration - 使用替代已废弃的单元格属性
UIContentConfiguration - 快照中无重复标识符(避免崩溃)
BUG_IN_CLIENT - 自调整单元格有明确的从上到下约束链
Navigation
导航
- All 4 slots configured
UINavigationBarAppearance - Appearance set on in
navigationItem, notviewDidLoadinnavigationBarviewWillAppear - Concurrent transition guard in place
- set once;
prefersLargeTitlesper VClargeTitleDisplayMode
- 配置了全部4个插槽
UINavigationBarAppearance - 在中为
viewDidLoad设置外观,而非在navigationItem中设置viewWillAppearnavigationBar - 存在并发转场防护
- 仅设置一次;每个VC单独设置
prefersLargeTitleslargeTitleDisplayMode
Animation
动画
- Correct API chosen for use case (animate vs PropertyAnimator vs CA)
- state machine respected
UIViewPropertyAnimator - Constraint animation uses correct pattern (flush → update → animate)
- sets model value before adding animation
CAAnimation - Completion handlers check parameter
finished
- 根据场景选择了正确的API(animate/PropertyAnimator/CA)
- 遵循状态机规则
UIViewPropertyAnimator - 约束动画使用正确模式(刷新 → 更新 → 动画)
- 在添加动画前设置了模型值
CAAnimation - 完成回调检查了参数
finished
Memory Management
内存管理
- in all escaping closures
[weak self] - Timers use block-based API with ; invalidated in
[weak self]viewWillDisappear - Task references stored and cancelled in
viewDidDisappear - CADisplayLink uses weak proxy pattern
- Delegates declared as on
weak var-constrained protocolAnyObject - No strong self re-capture in nested stored closures
- 所有逃逸闭包都使用了
[weak self] - Timer使用基于block的API并搭配;在
[weak self]中失效viewWillDisappear - Task引用被存储并在中取消
viewDidDisappear - CADisplayLink使用弱代理模式
- 委托声明为且协议带有
weak var约束AnyObject - 嵌套存储闭包中无强引用self的重捕获
Concurrency
并发
- checked after
Task.isCancelledbefore UI updatesawait - No for UI work without explicit
Task.detachedMainActor.run - No redundant on
@MainActorsubclasses (already inherited)UIViewController - No from background
DispatchQueue.main.sync
- 后更新UI前检查了
awaitTask.isCancelled - UI相关工作使用时显式添加了
Task.detachedMainActor.run - 子类无冗余的
UIViewController声明(已默认继承)@MainActor - 无从后台线程调用的情况
DispatchQueue.main.sync
Image Loading
图片加载
- Images downsampled to display size (not loaded at full resolution)
- Cell image loading: cancel in , clear image, verify identity
prepareForReuse - sized by decoded bitmap bytes, not file size
NSCache
- 图片按显示尺寸降采样(未加载全分辨率)
- 单元格图片加载:中取消、清空图片、完成时验证身份
prepareForReuse - 按解码后的位图字节数限制大小,而非文件大小
NSCache
UIKit–SwiftUI Interop
UIKit–SwiftUI互操作
- retained as stored property (not local variable)
UIHostingController - uses full child VC containment (
UIHostingController→addChild→addSubview)didMove - guards against infinite update loops with equality checks
updateUIView
- 作为存储属性持有(非局部变量)
UIHostingController - 使用完整的子VC容器化步骤(
UIHostingController→addChild→addSubview)didMove - 通过相等性检查防止无限更新循环
updateUIView
Keyboard
键盘
- Using (iOS 15+) instead of keyboard notifications
UIKeyboardLayoutGuide - iPad: on the layout guide
followsUndockedKeyboard = true
- 使用(iOS 15+)替代键盘通知
UIKeyboardLayoutGuide - iPad:布局向导设置了
followsUndockedKeyboard = true
Adaptive & Accessibility
自适应与无障碍
- (iOS 17+) instead of
registerForTraitChangestraitCollectionDidChange - Dynamic Type: +
preferredFontadjustsFontForContentSizeCategory = true - CGColor properties re-resolved on trait changes (layer.borderColor, shadowColor)
- Custom views have and
accessibilityLabelaccessibilityTraits - for complex list item actions
UIAccessibilityCustomAction
- 使用(iOS 17+)替代
registerForTraitChangestraitCollectionDidChange - 动态字体:使用+
preferredFontadjustsFontForContentSizeCategory = true - CGColor属性在特性变化时重新解析(layer.borderColor、shadowColor)
- 自定义视图设置了和
accessibilityLabelaccessibilityTraits - 复杂列表项操作使用
UIAccessibilityCustomAction
Modern APIs (iOS 26+)
现代API(iOS 26+)
- guards with sensible fallbacks for iOS 26+ features
#available - lifecycle adopted (mandatory for iOS 26 SDK)
UIScene - considered for iOS 18+ targets
UIObservationTrackingEnabled
- iOS 26+特性使用隔离并提供合理降级方案
#available - 已适配生命周期(iOS 26 SDK强制要求)
UIScene - iOS 18+目标考虑使用
UIObservationTrackingEnabled
References
参考文档
- — Lifecycle ordering, viewIsAppearing, child VC containment
references/view-controller-lifecycle.md - — Batch activation, constraint churn, priority, animation, debugging
references/auto-layout.md - — Diffable data sources, compositional layout, CellRegistration
references/modern-collection-views.md - — UIContentConfiguration, UIBackgroundConfiguration, configurationUpdateHandler
references/cell-configuration.md - — Prefetching, cell reuse, reconfigureItems, scroll performance
references/list-performance.md - — Bar appearance, concurrent transitions, large titles, deep links
references/navigation-patterns.md - — UIView.animate, UIViewPropertyAnimator, CAAnimation, springs
references/animation-patterns.md - — Retain cycles, [weak self], Timer/CADisplayLink/nested closure traps
references/memory-management.md - — @MainActor, Task lifecycle, Swift 6, GCD migration
references/concurrency-main-thread.md - — UIHostingController, UIViewRepresentable, sizing, state bridging
references/uikit-swiftui-interop.md - — Downsampling, decoded bitmap math, cell reuse race condition
references/image-loading.md - — UIKeyboardLayoutGuide, scroll view insets, iPad floating keyboard
references/keyboard-scroll.md - — Trait changes, Dynamic Type, dark mode, VoiceOver, accessibility
references/adaptive-appearance.md - — Observation framework, updateProperties(), .flushUpdates, UIScene, Liquid Glass
references/modern-uikit-apis.md
- — 生命周期顺序、viewIsAppearing、子VC容器化
references/view-controller-lifecycle.md - — 批量激活、约束频繁重建、优先级、动画、调试
references/auto-layout.md - — 差分数据源、组合布局、CellRegistration
references/modern-collection-views.md - — UIContentConfiguration、UIBackgroundConfiguration、configurationUpdateHandler
references/cell-configuration.md - — 预加载、单元格复用、reconfigureItems、滚动性能
references/list-performance.md - — 导航栏外观、并发转场、大标题、深度链接
references/navigation-patterns.md - — UIView.animate、UIViewPropertyAnimator、CAAnimation、弹簧动画
references/animation-patterns.md - — 循环引用、[weak self]、Timer/CADisplayLink/嵌套闭包陷阱
references/memory-management.md - — @MainActor、Task生命周期、Swift 6、GCD迁移
references/concurrency-main-thread.md - — UIHostingController、UIViewRepresentable、尺寸设置、状态桥接
references/uikit-swiftui-interop.md - — 降采样、解码位图计算、单元格复用竞争条件
references/image-loading.md - — UIKeyboardLayoutGuide、滚动视图内边距、iPad浮动键盘
references/keyboard-scroll.md - — 特性变化、动态字体、深色模式、VoiceOver、无障碍支持
references/adaptive-appearance.md - — Observation框架、updateProperties()、.flushUpdates、UIScene、Liquid Glass
references/modern-uikit-apis.md
Philosophy
设计理念
This skill focuses on facts and best practices, not architectural opinions:
- We don't enforce specific architectures (e.g., MVVM, VIPER, Coordinator)
- We do encourage separating business logic for testability
- We optimize for correctness first, then performance
- We follow Apple's documented APIs and Human Interface Guidelines
- We use "suggest" or "consider" for optional optimizations
- We use "always" or "never" only for correctness issues
本技能聚焦于事实与最佳实践,而非架构偏好:
- 不强制特定架构(如MVVM、VIPER、Coordinator)
- 但鼓励分离业务逻辑以提升可测试性
- 优先保证正确性,其次优化性能
- 遵循苹果官方文档API和人机界面指南
- 可选优化使用"建议"或"考虑"表述
- 仅在正确性问题上使用"必须"或"绝不"表述",