在SwiftUI中显示小吃店消息

djmepvbi  于 2023-08-02  发布在  Swift
关注(0)|答案(2)|浏览(100)

有没有一种方法可以使用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)我如何编写一个 Package 器函数,在任何SwiftUI View上显示消息,例如。在基于Storyboard的项目中,我们会传递类似topViewController或rootViewController的东西,以便在它上面显示UIView

yr9zkbsy

yr9zkbsy1#

您可以使用ViewModifier创建banner视图,然后在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))
    }
}

字符串

7nbnzgx9

7nbnzgx92#

我已经创建了下面的实用程序,易于使用,并支持所有呈现方向和动作按钮:
https://github.com/indrajitv/ICToastMessage
用途:

struct StraightForward: View {

    @State
    var show: Bool = false

    var body: some View {
        VStack {
            Button("Show") {
                self.show = true
            }
        }
        .padding()
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .setToastMessage(show: $show, text: "Lorem Ipsum is simply dummy text of the printing and typesetting industry.")
    }
}

字符串

相关问题