【问题标题】:Initialize Alert Outside Body View - SwiftUI初始化警报外部视图 - SwiftUI
【发布时间】:2020-03-05 01:12:28
【问题描述】:

这几天一直在尝试解决这个问题,现在是我寻求帮助的时候了。我知道如何使用普通的 Swift 来做到这一点,但目前 SwiftUI 对我来说还是有点不同。我有一个检查某事是否属实的功能。它通过 3 个 if 语句,如果一个为真,则它返回一个我创建为真的布尔值。一旦 3 个中的一个为真,我希望弹出某个警报。我已在正文中粘贴了所有 3 个警报:一些带有正确变量的视图,但它没有显示任何内容。如果我注释掉 2 并保留 1 Alert 未注释,那么它可以工作。所以我知道我的 if 语句是正确的。这就是我如何将它呈现给身体的方式,这就是我坚持的地方。请参阅下文,如果您有其他选择。

    func showTip() {
            if (stepFive <= Float(18)) {
                under = true
            }

           else if (stepFive >= Float(18) && stepFive <= Float(18.5)) {
                thin = true
            }


           else if (stepFive >= 18.6) && (stepFive <= 24.9) {
                healthy = true
            }
    }

var body: some View {
        ZStack {
            Color.blue
            .edgesIgnoringSafeArea(.all)

            .alert(isPresented: $under) {
                Alert(title: Text("Results"), message: Text("A of less than 18 means you are under weight. "), dismissButton: .default(Text("OK")))
            }

            .alert(isPresented: $thin) {
                Alert(title: Text("Results"), message: Text("A of less than 18.5 indicates you are thin"), dismissButton: .default(Text("OK")))
            }

            .alert(isPresented: $healthy) {
                Alert(title: Text("Results"), message: Text("A between 18.6 and 24.9 indicates you are at a healthy"), dismissButton: .default(Text("OK")))
            }
}

【问题讨论】:

    标签: swift xcode swiftui alert


    【解决方案1】:

    UPDATE 用于显示带有showTip 函数的解决方案:

    struct ComplexAlertWith3Variables: View {
    
        @State var under = false
        @State var thin = false
        @State var healthy = false
        @State var stepFive: Float = 18.3 // I don't know how it changes. From somewhere. and it doesn't matter now
    
        private var messageText: String {
            return thin ? "A of less than 18.5 indicates you are thin" : "" // compute other variants
        }
    
        var body: some View {
    
            let needToShowAlert: Binding<Bool> = Binding<Bool>(
            get: { self.under || self.thin || self.healthy },
            set: { if $0 == false { self.under = $0; self.thin = $0; self.healthy = $0 } })
    
            return Text("Fire show tip function, because I don't know from where it fires in your code")
                .onTapGesture { self.showTip() } // fire your function. so you see, it doesn't matter from where you change variables
                .alert(isPresented: needToShowAlert) {
                    Alert(title: Text("Results"), message: Text(self.messageText), dismissButton: .default(Text("OK")))
            }
    
        }
    
        // your function (makes it shorter to fit more lines of code)
        func showTip() {
            if (stepFive <= Float(18)) { under = true } 
            else if (stepFive >= Float(18) && stepFive <= Float(18.5)) { thin = true }
            else if (stepFive >= 18.6) && (stepFive <= 24.9) { healthy = true }
        }
    }
    

    点击文本时的结果会从其他地方触发功能:

    我对此进行了一些尝试,我想我可以为您提供一个解决方案。关于making custom Binding variable 并在body 中使用它。除了在第一个变体中,我使用enum 编写了决策,但您也可以在代码 sn-p 中找到具有 3 个变量的解决方案:

    struct ComplexAlert: View {
    
        @State private var option: SomeOption = .unselected
    
        var body: some View {
            // DISCLAIMER: I wrote in a such a way to fit more lines of code on the page
            // the main here is an idea, not code style =)
            let needToShowAlert: Binding<Bool> = Binding<Bool>(
                get: { self.option != .unselected },
                set: { if $0 == false { self.option = .unselected } })
    
            return VStack {
                Button(action: { self.option = .under }) { Text("make under") }
                Button(action: { self.option = .thin }) { Text("make thin") }
                Button(action: { self.option = .healthy }) { Text("make healthy") }
            }
                .alert(isPresented: needToShowAlert) {
                    Alert(title: Text("Results"), message: Text(self.option.getAlertMessage()), dismissButton: .default(Text("OK")))
            }
        }
    }
    
    // MARK: if you need to use 3 variables:
    struct ComplexAlertWith3Variables: View {
    
        @State var under = false
        @State var thin = false
        @State var healthy = false
    
        private var messageText: String {
            return under ? "under" : "" // compute other varianst
        }
    
        var body: some View {
    
            let needToShowAlert: Binding<Bool> = Binding<Bool>(
            get: { self.under || self.thin || self.healthy },
            set: { if $0 == false { self.under = $0; self.thin = $0; self.healthy = $0 } })
    
            return Text("Hello")
                .onTapGesture { self.under = true }
                .alert(isPresented: needToShowAlert) {
                    Alert(title: Text("Results"), message: Text(self.messageText), dismissButton: .default(Text("OK")))
            }
    
        }
    }
    
    // MARK: enum which was used in the first solution:
    enum SomeOption {
    
        case unselected
        case under
        case thin
        case healthy
    
        func getAlertMessage() -> String {
            switch self {
            case .unselected:
                return ""
            case .under:
                return "A of less than 18 means you are under weight. "
            case .thin:
                return "A of less than 18.5 indicates you are thin"
            case .healthy:
                return "A between 18.6 and 24.9 indicates you are at a healthy"
            }
        }
    
    }
    

    ComplexAlert 的结果将是:

    【讨论】:

    • 感谢您的帮助!不幸的是,该应用程序无法使用按钮。 showTip() 根据文本中显示的一些结果触发。然后它将其中一个布尔值返回为真,它应该显示一个警报。 IDK 为什么 Apple 在 SwiftUI 中让这变得有些复杂
    • @Dewan 好的,所以.. 代码 sn-p 中的示例 ComplexAlertWith3Variables 也是如此,它仅在 3 个布尔变量之一更改为 true 时显示警报。而且它们可以随处变化,无论你是用按钮还是在某些功能中改变它都没有关系。尝试添加您的 showTip 函数并从某处调用它。 - 结果是一样的
    • 我实际上阅读了您之前所说的内容,并使其与我的代码一起使用。和你做的方式非常相似。非常感谢!这是一个很好的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    • 2021-05-17
    • 2022-01-23
    相关资源
    最近更新 更多