在 SwiftUI 中显示小吃店消息
Posted
技术标签:
【中文标题】在 SwiftUI 中显示小吃店消息【英文标题】:show snack bar message in SwiftUI 【发布时间】:2020-05-22 02:29:04 【问题描述】:有没有办法使用 SwiftUI 显示 HStack
之类的小吃店消息,该消息会在 (n) 秒后消失?
我有以下结构,它是我的消息的容器:
struct MessageBuilder<Content>: View where Content: View
let content: () -> Content
init(@ViewBuilder content: @escaping () -> Content)
self.content = content
var body: some View
content()
我调用MessageBuilder
结构如下:
MessageBuilder
HStack
Image("MyImage")
Text("Some Message")
我有两个问题:
(1) 如何在屏幕顶部显示它然后自动关闭它(如SwiftMessages)?
(2) 我如何编写一个包装函数,在任何 SwiftUI View
上方显示消息,例如。在基于Storyboard
的项目中,我们将传递类似topViewController 或rootViewController
的内容,以便在其顶部显示UIView
。
【问题讨论】:
【参考方案1】:您可以使用ViewModifier
创建横幅视图,然后在您的 SwiftUI 中将其作为修饰符调用。
在您的修改器中使用 ZStack 在您的内容顶部显示横幅。
这是创建横幅并显示在视图顶部的简单示例
在您看来,您可以使用.banner(data: $bannerData, show: $showBanner)
来展示横幅
struct BannerData
var title: String
var detail: String
var type: BannerType
enum BannerType
case info
case warning
case success
case error
var tintColor: Color
switch self
case .info:
return Color(red: 67/255, green: 154/255, blue: 215/255)
case .success:
return Color.green
case .warning:
return Color.yellow
case .error:
return Color.red
struct BannerModifier: ViewModifier
@Binding var data: BannerData
@Binding var show: Bool
@State var task: DispatchWorkItem?
func body(content: Content) -> some View
ZStack
if show
VStack
HStack
VStack(alignment: .leading, spacing: 2)
Text(data.title)
.bold()
Text(data.detail)
.font(Font.system(size: 15, weight: Font.Weight.light, design: Font.Design.default))
Spacer()
.foregroundColor(Color.white)
.padding(12)
.background(data.type.tintColor)
.cornerRadius(8)
.shadow(radius: 20)
Spacer()
.padding()
.animation(.easeInOut(duration: 1.2))
.transition(AnyTransition.move(edge: .top).combined(with: .opacity))
.onTapGesture
withAnimation
self.show = false
.onAppear
self.task = DispatchWorkItem
withAnimation
self.show = false
// Auto dismiss after 5 seconds, and cancel the task if view disappear before the auto dismiss
DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: self.task!)
.onDisappear
self.task?.cancel()
content
extension View
func banner(data: Binding<BannerData>, show: Binding<Bool>) -> some View
self.modifier(BannerModifier(data: data, show: show))
【讨论】:
这是一个不错且简单的实现,但是,消息背景视图是半透明的,我尝试使用不透明度值更改所有颜色但无济于事,您是否知道如何使其背景具有纯色而不是半透明? 我不明白。在上面的例子中,横幅背景是实心的,后面有阴影,当它出现在内容上时不是半透明的 这是因为显示消息的视图位于 VStack 下 如果我有一个只有VStack
或 ZStack
的视图,当我在每个视图上使用 BannerModifier 时,如果我这样使用它就不会出现:ZStack ....banner(..)
或VStack....banner(...)
,要使其正常工作,我必须始终使用 ZStack
进行设置,并且必须将以下行作为 ZStack
中的最后一个元素:EmptyView().banner(...)
,您可以直接在任何不需要使用这种解决方法的视图?
@JAHelia 解决您的问题的方法是 zIndex(_:)。默认情况下,zIndex 的值为 0(零)。您可以提供正值或负值来排列视图的重叠。链接:developer.apple.com/documentation/swiftui/group/3284926-zindex以上是关于在 SwiftUI 中显示小吃店消息的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI URLSession 中显示来自服务器的错误消息
SwiftUI中List数据源为空时如何在视图中心显示文本消息?