SwiftUI:创建自定义警报
Posted
技术标签:
【中文标题】SwiftUI:创建自定义警报【英文标题】:SwiftUI: Creating custom alert 【发布时间】:2021-06-29 11:55:28 【问题描述】:我正在尝试抽象出一个在我的应用程序的多个地方使用的警报。
我复制并粘贴了func alert(isPresented: Binding<Bool>, content: () -> Alert) -> some View
的实现并对其进行了调整以适应我的使用:
extension View
func externalURLAlert(isPresented: Binding<Bool>, action: ()) -> some View
isPresented.wrappedValue ? AnyView(Alert(
title: Text("alert.externalURL.title".localized),
message: Text("alert.externalURL.message".localized),
primaryButton: .cancel(),
secondaryButton: .default(Text("alert.externalURL.openAction.title".localized))
action
)) : AnyView(EmptyView())
我的计划是在像 .externalURLAlert(isPresented: $isPresented, action: someAction)
这样的视图上调用它,但我无法编译该函数。
我得到的错误如下:
Initializer 'init(_:)' 要求 'Alert' 符合 'View'
【问题讨论】:
【参考方案1】:修饰符的工作方式是返回调用它们的视图的修改版本。如果您调用Text("").foregroundColor(...)
,您会收到一个带有新前景色的新Text
视图。警报也是如此,如果您调用Text("").alert(...
,您会收到一个Text
视图,该视图可以在顶部显示警报。
另一方面,您的修饰符会完全删除该层次结构并将其替换为空视图或警报,但此警报没有关于应在何处显示的信息。
如果您想要显示一个标准化的警报,您应该利用现有的修饰符和您自己的参数,如下所示:
extension View
func externalURLAlert(isPresented: Binding<Bool>, action: ()) -> some View
self.alert(isPresented: isPresented)
Alert(
title: Text("alert.externalURL.title".localized),
message: Text("alert.externalURL.message".localized),
primaryButton: .cancel(),
secondaryButton: .default(Text("alert.externalURL.openAction.title".localized))
action()
)
注意self
的使用,因为我们想要维护层次结构,而.alert(...)
因为我们正在使用已经知道如何显示警报的现有系统修饰符。
【讨论】:
【参考方案2】:尝试以下方法:
extension View
@ViewBuilder
func externalURLAlert(isPresented: Binding<Bool>, action: ()) -> some View
if isPresented.wrappedValue
Alert(
title: Text("alert.externalURL.title".localized),
message: Text("alert.externalURL.message".localized),
primaryButton: .cancel(),
secondaryButton: .default(Text("alert.externalURL.openAction.title".localized)) action
)
加上错误中写的你需要使Alert符合View。
还可以尝试使用 .sheet() -- 这看起来像您在搜索。
使用示例:https://www.hackingwithswift.com/quick-start/swiftui/how-to-present-a-new-view-using-sheets
或您通过 google 找到的任何内容 -> "swiftUI usage .sheet"
【讨论】:
这不起作用,因为您只是替换现有的层次结构。例如,如果您在NavigationView
上调用它,结果是 EmptyView
或 Alert
,但 NavigationView
消失了。
@EmilioPelaez 我只是展示了如何以正确的方式编写他的代码。那么主要问题呢? sheet() 将按他的预期工作。我在我的回答中写了关于工作表的内容。
如果它不编译(因为Alert
不符合View
)并且不起作用(因为即使它这样做了,因为我已经说,你正在清除视图层次结构)。以上是关于SwiftUI:创建自定义警报的主要内容,如果未能解决你的问题,请参考以下文章