如何显示多种类型的ConfirmationDialog?

huangapple go评论58阅读模式
英文:

How to show multiple kinds of ConfirmationDialog?

问题

与表格不同,ConfirmationDialog没有带有参数item: Binding<Item?>的初始化函数,唯一的函数是isPresented: Binding<Bool>,用于控制标题和按钮。

例如,在一个视图中,需要确认三种**种类(而不是单个项目)**的删除操作,每种操作需要不同的标题和按钮。

我不想将其分为3个视图或使用3个isPresented绑定。有什么建议吗?

英文:

Unlike sheet, ConfirmationDialog have no init func with parameter item: Binding<Item?>, the only one isPresented: Binding<Bool> to control title and buttons.

for example, in one view, there are 3 kinds(NOT pieces) of deletion actions need to confirm with different title and buttons for each.

I don't want to separate to 3 views or 3 isPresented bindings. any suggestion?

答案1

得分: 0

是的,我们可以使用 "presenting data: T?" 来识别 ConfirmationDialog 的类型,就像 sheet 的 Binding<Item?> 一样。我认为苹果设计 "isPresented: Binding" 只是为了简化使用而不是呈现。或者它可能不是必需的。

以下是一个示例(还可以查看有关 ConfirmationDialog 的全部代码):

enum ConfirmationID {
    case test1
    case test2
    case test3
    
    var id: ConfirmationID { self }
}

struct ConfirmationItem: Identifiable {
    var id: ConfirmationID
    var item: String
}

struct ConfirmationDialog0: View {
    @State private var messages: [Int] = (0..<5).map { $0 }
    @State private var isPresented: Bool = false
    @State private var confirmationItem: ConfirmationItem?
    
    var body: some View {
        NavigationView {
            GeometryReader { proxy in
                ScrollView {
                    HStack {
                        Button("test 1") {
                            confirmationItem = ConfirmationItem(id: .test1, item: "test 1")
                            isPresented = true
                        }
                        Button("test 2") {
                            confirmationItem = ConfirmationItem(id: .test2, item: "test 2")
                            isPresented = true
                        }
                        Button("test 3") {
                            confirmationItem = ConfirmationItem(id: .test3, item: "test 3")
                            isPresented = true
                        }
                    }
                    List {
                        ForEach(messages, id: \.self) { message in
                            itemView0(message: message) { _ in
                                withAnimation {
                                    messages = messages.filter { $0 != message }
                                }
                            }
                        }
                    }
                    .frame(height: proxy.size.height)
                }
            }
            .navigationTitle("WRONG if .destructive!")
            .confirmationDialog("CONFIRM", isPresented: $isPresented, titleVisibility: .visible, presenting: confirmationItem, actions: confirmationDialogActionsView, message: confirmationDialogMassageView)
        }
    }
    
    @ViewBuilder
    func confirmationDialogActionsView(item: ConfirmationItem) -> some View {
        switch item.id {
            case .test1:
                Button(action: {}) {
                    Text("do with item \(item.item): ") + Text(Image(systemName: "star")) + Text(" World!")
                }
            case .test2:
                Button("delete with item \(item.item)", role: .destructive) {}
                Button(action: {}) {
                    Text("""
                        delete with item \(item.item)
                        CANNOT undo this action!!!
                        """)
                }
            case .test3:
                Button(action: {}) {
                    VStack {
                        Text("play with item \(item.item)")
                        Text("Have a good time!")
                    }
                }
            }
            Button("Cancel", role: .cancel) {
                confirmationItem = nil
            }
    }
    
    func confirmationDialogMassageView(item: ConfirmationItem) -> some View {
        switch item.id {
            case .test1:
                return Text("Confirm to do with item \(item.item)")
            case .test2:
                return Text("Confirm to delete item \(item.item)")
            case .test3:
                return Text("Confirm to play with item \(item.item)")
        }
    }
}

struct itemView0: View {
    @State private var confirmationShown = false
    let message: Int
    let onDelete: (Int) -> Void
    
    var body: some View {
        Text("\(message)")
            .swipeActions {
                Button(
                    role: .none,
                    action: { confirmationShown = true }
                ) {
                    Image(systemName: "trash")
                }
                .tint(Color.red)
            }
            .confirmationDialog(
                "Are you sure?",
                isPresented: $confirmationShown,
                titleVisibility: .visible,
                presenting: message
            ) { message in
                Button("Yes, delete: \(message)") {
                    onDelete(message)
                }.keyboardShortcut(.defaultAction)

                Button("No", role: .cancel) {}
            } message: { message in
                Text("\(message)")
            }
    }
}
英文:

Yes, we can use "presenting data: T?" to identify the kinds of ConfirmationDialog, just like Binding<Item?> of sheet. I think apple design "isPresented: Binding<Bool>" just to simplify usage without presenting. OR it's not necessary.

here is an example (also see the whole code about ConfirmationDialog):

enum ConfirmationID {
case test1
case test2
case test3
var id: ConfirmationID { self }
}
struct ConfirmationItem: Identifiable {
var id: ConfirmationID
var item: String
}
struct ConfirmationDialog0: View {
@State private var messages: [Int] = (0..&lt;5).map { $0 }
@State private var isPresented: Bool = false
@State private var confirmationItem: ConfirmationItem?
var body: some View {
NavigationView {
GeometryReader { proxy in
ScrollView {
HStack {
Button(&quot;test 1&quot;) {
confirmationItem = ConfirmationItem(id: .test1, item: &quot;test 1&quot;)
isPresented = true
}
Button(&quot;test 2&quot;) {
confirmationItem = ConfirmationItem(id: .test2, item: &quot;test 2&quot;)
isPresented = true
}
Button(&quot;test 3&quot;) {
confirmationItem = ConfirmationItem(id: .test3, item: &quot;test 3&quot;)
isPresented = true
}
}
List {
ForEach(messages, id: \.self) { message in
itemView0(message: message) { _ in
withAnimation {
messages = messages.filter { $0 != message }
}
}
}
}
.frame(height: proxy.size.height)
}
}
.navigationTitle(&quot;WRONG if .destructive!&quot;)
.confirmationDialog(&quot;CONFIRM&quot;, isPresented: $isPresented, titleVisibility: .visible, presenting: confirmationItem, actions: confirmationDialogActionsView, message: confirmationDialogMassageView)
}
}
@ViewBuilder
func confirmationDialogActionsView(item: ConfirmationItem) -&gt; some View {
//        Group {
switch item.id {
case .test1:
Button(action: {}) {
Text(&quot;do with item \(item.item): &quot;) + Text(Image(systemName: &quot;star&quot;)) + Text(&quot; World!&quot;)
} // NOTE: Text(Image(systemName: &quot;star&quot;)) does not work
case .test2:
Button(&quot;delete with item \(item.item)&quot;, role: .destructive) {}
Button(action: {}) {
Text(&quot;&quot;&quot;
delete with item \(item.item)
CANNOT undo this action!!!
&quot;&quot;&quot;)
} // NOTE: multiple lines text does not work. FYI: https://developer.apple.com/documentation/swiftui/view/confirmationdialog(_:ispresented:titlevisibility:presenting:actions:)-51pyu
case .test3:
Button(action: {}) {
VStack {
Text(&quot;play with item \(item.item)&quot;)
Text(&quot;Have a good time!&quot;) // NOTE: multiple texts do not work either.
}
}
}
Button(&quot;Cancel&quot;, role: .cancel) {
confirmationItem = nil
}
//        }
}
func confirmationDialogMassageView(item: ConfirmationItem) -&gt; some View {
switch item.id {
case .test1:
return Text(&quot;Confirm to do with item \(item.item)&quot;)
case .test2:
return Text(&quot;Confirm to delete item \(item.item)&quot;)
case .test3:
return Text(&quot;Confirm to play with item \(item.item)&quot;)
}
}
}
struct itemView0: View {
@State private var confirmationShown = false
let message: Int
let onDelete: (Int) -&gt; Void
var body: some View {
Text(&quot;\(message)&quot;)
.swipeActions {
Button(
role: .none,//.destructive,
action: { confirmationShown = true }
) {
Image(systemName: &quot;trash&quot;)
}
.tint(Color.red)
}
.confirmationDialog(
&quot;Are you sure?&quot;,
isPresented: $confirmationShown,
titleVisibility: .visible,
presenting: message
) { message in
Button(&quot;Yes, delete: \(message)&quot;) {
onDelete(message)
}.keyboardShortcut(.defaultAction)
Button(&quot;No&quot;, role: .cancel) {}
} message: { message in
Text(&quot;\(message)&quot;)
}
}
}

huangapple
  • 本文由 发表于 2023年3月7日 23:29:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75663974.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定