为什么在SwiftUI中,当使用.sheet呈现模态视图时,init()被调用两次

scyqe7ek  于 2023-03-16  发布在  Swift
关注(0)|答案(5)|浏览(152)

我使用以下代码在WatchOS上生成了这种情况

struct Modal : View {
    @Binding var showingModal : Bool
    
    init(showingModal : Binding<Bool>){
        self._showingModal = showingModal
        print("init modal")
    }
    
    var body: some View {
        Button(action: {
            self.showingModal.toggle()
        }, label: {
            Text("TTTT")
        })
    }
}

struct ContentView: View {
    @State var showingModal = false
    var body: some View {
        Button(action: {
            self.showingModal.toggle()
        }, label: {
            Text("AAAA")
        }).sheet(isPresented: $showingModal, content: {Modal(showingModal: self.$showingModal)})
    }
}

每次我按下主视图中的按钮,用.sheet调用模态视图时,就会创建模态视图的两个示例。
有人能解释这种现象吗?

olmpazwi

olmpazwi1#

我在我的代码中找到了这一点,在我的视图中有下面一行:

@Environment(\.presentationMode) var presentation

由于https://stackoverflow.com/a/61311279/155186,我一直在这样做,但由于某种原因,这个问题似乎已经消失了,所以我想我不再需要它。
我已经就此向苹果提交了反馈FB7723767。

1l5u6lss

1l5u6lss2#

从Xcode 11.4.1(11E503a)开始,这可能是一个bug。请注意,例如,如果初始化视图模型(或任何其他类似的东西)如下:

.sheet(isPresented: $isEditingModalPresented) {
    LEditView(vm: LEditViewModel(), isPresented: self.$isEditingModalPresented)
}

VM将被初始化两次。

xvw2m8pv

xvw2m8pv3#

从Modal中注解/删除init()方法,其他内容保持不变。您应该能够解决创建两个Modal示例的问题,这是因为您在Modal的init()中显式初始化绑定(showingModal)。希望这有意义。

kg7wmglp

kg7wmglp4#

private let uniqueId: String = "uniqueId" 

Button(action: {
    self.showingModal.toggle()
}, label: {
    Text("AAAA")
})
    .sheet(isPresented: $showingModal) {
        Modal(showingModal: self.$showingModal)
          .id("some-unique-id")
    }

例如:
.id(自身唯一ID)
添加唯一的ID到你的.sheet,不用担心:)
But, do not use UUID(), because sheet view will be represented on every touch event

bfhwhh0e

bfhwhh0e5#

似乎是sheetfullScreenCover修饰符中的一个bug。在我的例子中,它在显示、隐藏键盘和键入之后也调用了它的content闭包。为了防止视图被重新创建,我们可以将它 Package 在一个采用Equatable的视图中,它总是等于它的示例:

struct PersistentContentView<Content: View>: View, Equatable {
    static func == (lhs: PersistentContentView<Content>, rhs: PersistentContentView<Content>) -> Bool {
        true
    }

    let content: () -> Content

    var body: some View {
        content()
    }
}

extension View {
    func persistent() -> some View {
        PersistentContentView { self }
    }
}
.sheet(isPresented: $showingModal) {
        Modal(showingModal: self.$showingModal)
            .persistent()
    }

相关问题