列表中的 UIViewRepresentable 行在 SwiftUI 中消失
Posted
技术标签:
【中文标题】列表中的 UIViewRepresentable 行在 SwiftUI 中消失【英文标题】:UIViewRepresentable Rows In List Disappearing in SwiftUI 【发布时间】:2020-11-13 03:56:05 【问题描述】:我有这个列表:
struct SignInList: View
@ObservedObject var model:SignInModel
var body: some View
List(model.currentSignIns) signIn in
SignInRow(description: signIn)
使用此列表行:
struct SignInRow: View, Identifiable
let id = UUID()
let description: SignInDescription
var body: some View
VStack
ButtonView(view: description.button)
// Map a UIView to a View. Will be using this to hold a UIView based sign-in button
// https://developer.apple.com/tutorials/swiftui/creating-and-combining-views
struct ButtonView: UIViewRepresentable
let view: UIView
func makeUIView(context: Context) -> UIView
return view
func updateUIView(_ uiView: UIView, context: Context)
但是当我滚动列表时,列表的单元格消失了:
Cells Disappearing
如果我将列表单元格更改为纯 SwiftUI,例如,
struct SignInRow: View, Identifiable
let id = UUID()
let description: SignInDescription
var body: some View
VStack
Rectangle()
我没有得到这个效果。滚动时单元格不会消失。
我已经尝试了一些关于 SO 的想法(例如,SwiftUI and ScrollView: Views Disappear After Device Rotation 和 Content in scrollview as a list item disappears when scrolling (swiftui), why?),但到目前为止没有真正的改进。 (当我在 ScrollView 中嵌入 ForEach 时,我遇到了不同的问题 - 我的两行中只显示了一个,并且按钮不再可点击)。
【问题讨论】:
【参考方案1】:我认为@Asperi 走在正确的轨道上,List
是问题所在。我正在放弃使用它们。以下是现在对我有用的方法:
struct SignInList: View
@ObservedObject var model:SignInModel
var body: some View
ScrollView()
ForEach(model.currentSignIns) signIn in
SignInRow(description: signIn)
.padding(.horizontal, 20)
struct SignInRow: View, Identifiable
let id = UUID()
let description: SignInDescription
var body: some View
VStack
ButtonView(view: description.button)
.frame(height: 40)
【讨论】:
【参考方案2】:我认为问题是因为 List 重用了行,所以它从 superview 中删除了您从外部注入的 UIView,但之后不要再次插入它(这不是可表示的工作方式),而只是更新。
一般模式是您应该提供数据,但视图应该在makeView
中创建并在updateView
中更新。
这是从您的代码中复制的一些简化演示。使用 Xcode 12.1 / ios 14.1 测试。
class SignInModel: ObservableObject
@Published var currentSignIns = (1..<100).map "\($0)"
struct SignInList: View
@ObservedObject var model = SignInModel()
var body: some View
List(model.currentSignIns) signIn in
SignInRow(description: signIn)
struct SignInRow: View, Identifiable
let id = UUID()
let description: String
var body: some View
VStack
ButtonView(title: description)
struct ButtonView: UIViewRepresentable
let title: String
func makeUIView(context: Context) -> UIView
let button = UIButton(type: .system)
button.setTitle(title, for: .normal)
return button
func updateUIView(_ uiView: UIView, context: Context)
【讨论】:
嘿,谢谢。也许这个的一些变化可以解决这个问题。我认为仍然缺少一些东西。如果您将新的ButtonView
结构更改为具有生成 UIButton
的构造函数,并且在每次调用 UIButton
时仅返回相同的 UIButton
实例@,这仍然以相同的方式工作。即,列表单元格不会消失。以上是关于列表中的 UIViewRepresentable 行在 SwiftUI 中消失的主要内容,如果未能解决你的问题,请参考以下文章
MapView:UIViewRepresentable 不以获取的列表为中心
更新 SwiftUI 中的 inputAccessoryView (UIViewRepresentable)
TableView 重新加载不适用于 SwiftUI 中的 UIViewRepresentable
我如何使用Combine来跟踪UIViewRepresentable类中的UITextField更改?
可调整大小的 UITextView 的 sizeThatFits 在 UIViewRepresentable 中给出了错误的大小