近期,苹果开发者网站发起了Ask Apple活动,邀请开发人员直接与苹果专家沟通。
活动时间是2022年10月17-21日,目前活动已结束。
苹果为我们保留了本次活动中所有内容供开发者查阅。
我认为有必要在这里对一些感兴趣相关专题中问答内容进行汇总并翻译,供大家参考。
由于水平有限,文中的翻译可能有些不准确或有些小错误,还望大家在阅读过程中理解。如果您发现错误或有更好的想法,欢迎指正🙌🏻
本篇是关于SwiftUI的问答内容汇总。由于内容较多,为了控制篇幅,我会将所有该专题内容整理为三个部分,这是第一部分。📚
SwiftUI
NavigationSplitView故障问题
Developer:
使用
NavigationSplitView
,当详细信息是列表时,侧边栏的打开和关闭会重新加载整个详细信息视图,从而产生故障。单元格不会展开或收缩,它们只是用新框架重新加载,然后滑动到位置。我认为同样的错误出现在UITable / CollectionView
中(我认为由hood
下的列表使用)。是否有一些解决方法? 如果详细信息视图是堆栈,则 UI 会完全收缩和扩展。
Apple:
您是否尝试过iOS 16.1 bata?我们在16.1中修复了与
NavigationSplitView
相关的许多问题。
关于为共享表添加“原生”SwiftUI 支持
Developer:
是否有计划在不使用 UIActivityView控制器的情况下为 iOS 系统共享表添加“原生”SwiftUI 支持
Apple:
现在可以使用!请查看共享链接 developer.apple.com/documentati…
Developer:
可敬的,感谢!😊
.contextAction
修饰符会重现回来吗
Developer:
在早期的 iOS 16 和 macOS 13 测试版之一中,我们看到了一个新的
.contextAction
修饰符,后来被删除了。是否有任何建议来检测列表中的行选择,类似于“NavigationLink”,但不导航到另一个视图(例如,显示工作表或从列表中选择一个选项)?按钮在iOS和iPadOS可以很好适配,但在macOS上适配得不是很好。此外,.contextAction
支持多选。它会回来吗?
Apple:
查看上下文菜单修饰符的主要操作参数。(这里是文档)。该 API 还具有一个用于选择类型的参数,允许您支持多选。
Developer:
感谢你,Harry!
是否有在 SwiftUI 视图中测试@State变量的推荐方式?
Developer:
是否有在 SwiftUI 视图中测试@State变量的推荐方式?还是将这些变量重构为视图模型的唯一方式?
Apple:
如果在同一视图中,您有一堆相互依赖的@State属性,则最好将其提取到其自己的结构中,以便您可以测试代码中的不变量。 将其提取到自己的视图模型中也是一种策略,但这不是必需的。
关于TextFields
的
Developer:
您好,首先非常感谢和祝贺这一举措。我的问题是关于
TextFields
的。 假设我们要创建一个类似于iMessage的视图,您可以在其中看到一个消息列表(与本例无关)和视图底部的文本字段。当用户点击文本字段时,键盘的工具栏中将显示一个文本字段。 我尝试在工具栏项组中添加一个文本文件(placement:.bottomBar
)和工具栏项目组中添加第二个文本文件(placement:.keyboard
),然后在@FocusState
变量的帮助下,我可以隐藏一个并将焦点更改为键盘。这有点笨拙,我不认为有2个TextFields
是好的实现方式。同样,按照此方法,@FocusState
变量无响应,并且无法将其设置为 nil(返回到上一个视图且不会移除键盘)。 是否可以在纯 SwiftUI 中完成(不使用 UIKit)? 你能给我一些指导来完成它吗?
Apple:
一般来说,我建议使用这种实现方式:
.safeAreaInset(edge: .bottom) { MyTextField() }
用于永久位于底部的文本字段。然后,您可以使用焦点状态来自定义其背景,无论其是否聚焦。 希望这适用于您的设计。
如何在来自不同subtrees的两个子视图之间共享状态
Developer:
如何在来自不同subtrees的两个子视图之间共享状态(例如可观察对象),而不被动地调用顶级视图的视图正文? (假设我可以在父视图中具有状态对象,并通过环境对象传递对象。但是,如果内部的 @Published 属性发生更改,则父视图及其subtree也将重新计算)
Apple:
EnvironmentObject
是一个很好的工具。如果您不希望父级也更新,则可以在创建对象时不使用@StateObject
或@ObservedObject
。
Developer:
意思是只是顶层视图中的一个属性,但仍然传递到
.environmentObject()
?
Apple:
没错~
Developer:
感谢~
是否可以检查NavigationPath
,以查看我是否通过 SearchView
到达了某个视图
Developer:
我很高兴看到新的
NavigationStack/NavigationPath
,它对我来说运行良好。 我想知道我是否可以检查NavigationPath
,以查看我是否通过SearchView
到达了某个视图(作为一个示例)。 我确实找到了一个使用NavigationPath.CodableRepresentation
实现的想法,但我担心这可能不是检查我的异构堆栈元素的最佳或最可持续的方式。 谢谢!
Apple:
目前没有内省
NavigationPath
的方式。如果您需要知道路径的内容,一个好的方法是使用同构路径,如下所示:
@State private var path: [MyEnum]
然后,您的
navigationDestination
将打开枚举类型。(已编辑)
关于Swift图标拖动事件监听问题
Developer:
我有一个 Swift 图表,在其中监听拖动事件并在拖动期间显示规则标记。在拖动过程中,y 轴刻度变大。在我的情况下,它不拖动时从0到75,在拖动期间从0到100。有没有办法防止这种情况?
Apple:
默认的 y 刻度会自动考虑规则标记的 y 值及其周围的任何注释。您可以使用以下命令修复 y 尺度域:
.chartYScale(domain: 0 ... 75)
,或者尝试确保规则和规则周围的任何注释不超过 75。
关于 iOS 16.x 中键盘安全区域的问题
Developer:
我们的用户继续报告 iOS 16.x 中键盘安全区域的问题。要点是键盘关闭根本不更新安全区域,这会在我们的UI中留下大键盘大小的孔。对于我们(以及我们所知道的其他一些社区成员)提交的反馈问题,系统是否有任何更新?
为了使这个问题不那么模糊,我从归档的反馈中复制了一些步骤来重现这个问题。
若要进行测试,请在随附的项目中尝试以下步骤:
- 通过选择按钮显示工作表
- 通过关注文本字段来触发键盘
- 开始以交互方式缓慢地关闭工作表 此时,系统将从文本字段中重新分配焦点并关闭键盘。
- 取消交互式关闭手势
请注意,两个
SheetView
子项(黄色和绿色)现在都位于键盘所在的位置,因为它尊重键盘的安全区域。
``` import SwiftUI @main struct Application: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { @State var isPresented = false var body: some View { Button("Present") { isPresented = true } .sheet(isPresented: $isPresented) { SheetView() } } } struct SheetView: View { @State var text = "" var body: some View { ZStack(alignment: .bottom) { Color.yellow .overlay(alignment: .top) { TextField("Type something here...", text: $text) .padding() } Color.green .frame(height: 100) } } }
Apple:
你能链接到你提交的反馈吗?
Developer:
👋🏻FB11618967
Apple:
感谢,我会看的。
Developer:
我还提交了一个与此类似的问题(发布以继续)
FB11701808
是否可以根据模型的更改对视图进行动画处理
Developer:
你好!是否有任何其他方法可以根据模型的更改对视图进行动画处理,而无需使用 onChange 修饰符? 我的代码是这样的:
@EnvironmentObject var model: MyModel @State var isAnimated: Bool = false var body: some View { … .onChange(of: modle.state.aChange( { value in withAnimation(…) { self.isAnimated = value } } }
Apple:
您可以使用
.animation(value:)
直接使用模型(无需额外的@State
属性)对更改进行动画处理修饰语:.animation(.easeInOut, value: model.state)
这将对由
model.state
更改导致的任何更改进行动画处理。
Developer:
多谢,我会试试看!
如何在 iOS 16 中显示与动态内容高度匹配的底部工作表?
Developer:
如何在 iOS 16 中显示与动态内容高度匹配的底部工作表?简言之,我想在
presentationDetents
中使用视图高度。
Apple:
谢谢你的问题。目前这是不可能的,但这是我们感兴趣的。
将来是否会有@ToolbarBuilder
或者对if condition { ToolbarItem(a) } else { ToolbarItem(b) }
更好的支持?
Developer:
将来是否会有
@ToolbarBuilder
或者对if condition { ToolbarItem(a) } else { ToolbarItem(b) }
更好的支持?
Apple:
首先你可能永远没法使用
@ToolbarBuilder
,但是我们会提供@ToolbarContentBuilder
,它会在iOS 16获得一些新特性。
ToolbarContentBuilder
的支持(及其它)和符合ToolbarContent
的自定义类型现在支持动态属性,如@Environment/@EnvironmentObject
。
Developer:
感谢++!这正是我需要的。
是否有任何关于何时/是否有多个场景的指导或示例?
Developer:
👋🏻早上好!我对 SwiftUI(及苹果开发!) 很陌生 – 我的问题是关于场景的。
在我一直在探索的几乎所有教程和其他示例代码库中,只有一个
WindowGroup
场景,所有实际操作都嵌套在InentView()
中 - 是否有任何关于何时/是否有多个场景的指导或示例?还是大多数应用只是嵌套在单个窗口组中?
Developer(好心的路人):
您最需要多个场景来构建多个场景,例如“页面”或“数字”应用
Apple:
多个场景对于构建更复杂的应用程序非常有用,尤其是在 macOS 上。例如,您可能希望有一个同时定义
DocumentGroup
和DocumentGroup
的应用程序,或者一个具有DocumentGroup
和辅助Window
场景的应用程序。场景的内容视图定义了场景创建的窗口中的视图内容,但场景本身定义了应用程序的整体结构。
Developer:
多谢你们所有人,很有帮助
那么每个iOS应用程序都是一个单一的场景吗?
Apple:
它不一定是必须的。在 iPadOS 上,您可以定义多个场景并使用
OpenWindowAction
操作来激活它们。
Developer:
多谢Jeff!
关于SwiftUI的第一部分就到这里啦,后续会跟进整理第二部分和第三部分,敬请期待!⏳