繁体   English   中英

列表中的 UIViewRepresentable 行在 SwiftUI 中消失

[英]UIViewRepresentable Rows In List Disappearing in SwiftUI

我有这个清单:

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) {
    }
}

但是当我滚动列表时,列表的单元格消失了:

细胞消失

如果我将列表单元格更改为纯 SwiftUI,例如,

struct SignInRow: View, Identifiable {
    let id = UUID()
    let description: SignInDescription
    
    var body: some View {
        VStack {
            Rectangle()
        }
    }
}

我没有得到这种效果。 滚动时单元格不会消失。

我在 SO 上尝试了一些想法(例如, SwiftUI 和 ScrollView:视图在设备旋转后消失,滚动视图中的内容作为列表项在滚动时消失(swiftui),为什么? )但到目前为止没有真正的改进。 (当我在 ScrollView 中嵌入 ForEach 时,我遇到了不同的问题——我的两行中只有一行显示出来,按钮不再可点击)。

我认为@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)
    }
}

我假设这个问题是因为 List 重用行,所以它从 superview 中删除了外部注入的 UIView,但之后不要再次插入它(这不是可表示的工作方式),而只是更新。

一般来说,模式是您应该提供数据,但视图应该在updateView中创建并在makeView中更新。

这是从您的代码中复制的一些简化演示。 使用 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) {
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM