概述
原本在 iOS 17 中运行良好的 SwiftUI 代码突然在 iOS 18 无法正常工作了,具体表现为原来视图中的的点击手势无法响应。
这是怎么回事呢?
且看分解!Let’s go!!!😉
问题现象
从下面的演示代码可以看到,我们在 List 容器的 ForEach 视图上添加了点击手势:
List {
ForEach(showingDialogues, id: \.self) { dialog in
Text(dialog)
.font(.title3.weight(.bold))
.listRowSeparator(.hidden)
}
.onTapGesture {
if index < dialogues.count {
showingDialogues.append(dialogues[index])
index += 1
} else {
isShowQuizView = true
}
}
}
这在 iOS 17 中工作正常,但是升级至 iOS 18 后点击却无任何反应,检查发现是点击手势的回调并没有被触发。
解决之道
解决非常简单,我们只需将原来直接附着在 ForEach 上的手势修改器移动至外层(比如 List 上)即可:
List {
ForEach(showingDialogues, id: \.self) { dialog in
Text(dialog)
.font(.title3.weight(.bold))
.listRowSeparator(.hidden)
}
}
.listStyle(.plain)
.onTapGesture {
if index < dialogues.count {
showingDialogues.append(dialogues[index])
index += 1
} else {
isShowQuizView = true
}
}
究其原因,我们注意到:之前旧代码中视图在显示时 showingDialogues 状态数组的内容为空。
@State var showingDialogues = [String]()
这在 iOS 18 之前的系统里,ForEach 仍会产生可点击范围,但是在 iOS 18 中并不会。
我们猜测原因是 iOS 18 对视图可见性检查更加严格了。因为按照常理来说当 ForEach 构造器对应的集合为空时其不应该再产生可点击的范围,所以这是 iOS 18 行为更加严谨的表现。
希望本篇博文可以一解大家的燃眉之急。
更多苹果开发中恢诡谲怪的问题和奇妙的调试秘笈,请小伙伴们移步我的精品专栏《开发疑难秒懂百科》观赏更多精彩的内容。
总结
在本篇博文中,我们讨论了 iOS 18 中的 SwiftUi ForEach 视图点击逻辑和之前略有不同的情况,并给出解决方法。这可能是 SwiftUI 在 iOS 18 系统中变得更加严谨了。
感谢观赏!再会啦!😎