【问题标题】:How do you send values to other classes using ObservableObject in SwiftUI如何在 SwiftUI 中使用 ObservableObject 将值发送到其他类
【发布时间】:2021-05-31 11:19:07
【问题描述】:

我正在尝试创建一个简单的小费计算器,但是一旦用户在应用程序中添加信息而不是计算小费,我就会遇到问题,该函数会返回,就好像某处存在问题一样。

我试图做到这一点,以便当用户在文本字段中输入数字并选择百分比时,总提示会显示在下方。

我该如何解决这个问题? 我添加了一个打印语句来打印“returning”这个词,它一直在打印这个词,所以我认为问题出在 calculateTip 函数的某个地方:

这是我的 ContentView 类的代码:

struct ContentView: View {

//MARK: - PROPERTIES
@ObservedObject public var tipVM = TipViewModel()

//MARK: - FUNCTIONS
private func endEditing() {
    hideKeyboard()
}
     
//MARK: - BODY
var body: some View {
    Background {
        NavigationView {
            ZStack {
                VStack {
                    HStack(spacing: 10) {
                        Text("Tip Calculator")
                            .font(.system(.largeTitle, design: .rounded))
                            .fontWeight(.heavy)
                            .padding(.leading, 4)
                            .foregroundColor(.blue)
                        Spacer()
                        Button(action: {
//                                tipVM.clearFields()
                        }, label: {
                            Text("Clear")
                                .font(.system(size: 16, weight: .semibold, design: .rounded))
                                .padding(.horizontal, 10)
                                .frame(minWidth: 70, minHeight: 24)
                                .background(
                                    Capsule().stroke(lineWidth: 2)
                                )
                                .foregroundColor(.blue)
                        }) //: BUTTON
                    } //: HSTACK
                    .padding()
                    Spacer(minLength: 80)
                    TextField("Enter Amount: ", text: $tipVM.amount)
                        .padding()
                        .background(Color.secondary)
                        .foregroundColor(.white)
                        .font(.system(.title3, design: .rounded))
                    Picker(selection: $tipVM.tipPercentage, label: Text("Picker"), content: {
                        ForEach(0 ..< tipVM.tipChoices.count) { index in
                            Text("\(self.tipVM.tipChoices[index])%").tag(index)
                                .font(.system(.body, design: .rounded)).padding()
                        }.padding()
                        .background(subtitleColor)
                        .foregroundColor(.white)
                    }).onTapGesture(perform: {
                        tipVM.calculateTip()
                    })
                    .pickerStyle(SegmentedPickerStyle())
                    Text(tipVM.tip == nil ? "£0" : "\(tipVM.tip!)")
                        .font(.system(.largeTitle, design: .rounded))
                        .fontWeight(.bold)
                        .foregroundColor(.blue)
                        .padding()
                    
                } //: VSTACK
            } //: ZSTACK
            .navigationBarHidden(true)
        } //: NAVIGATION VIEW
        .navigationViewStyle(StackNavigationViewStyle())
    }.onTapGesture {
        self.endEditing()
    }
    .ignoresSafeArea(.keyboard, edges: .all)
} //: BACKGROUND
}

这是我的 TipViewModel 类的代码:

import Foundation
import SwiftUI
import Combine

class TipViewModel: ObservableObject {

var amount: String = ""
var tipPercentage: Int = 0
var tip: Double?

let tipChoices = [10,15,20,25,30]

let didChange = PassthroughSubject<TipViewModel, Never>()

func calculateTip() {

    guard let amount = Double(amount) else {
        print("returning")
        return
    }
    
    self.tip = amount * (Double(tipPercentage)/100)
    self.didChange.send(self)
}
}

感谢您的帮助。

【问题讨论】:

    标签: ios xcode swiftui observableobject


    【解决方案1】:

    通常的方法是用@Published 标记属性,其更改将被监控。不需要额外的Combine 主题。

    并将tip 声明为非可选

    import Foundation
    import SwiftUI
    // import Combine
        
    class TipViewModel: ObservableObject {
        
        var amount: String = ""
        var tipPercentage: Int = 0
        @Published var tip = 0.0
        
        let tipChoices = [10,15,20,25,30]
        
        func calculateTip() {
        
            guard let numAmount = Double(amount) else {
                print("returning")
                return
            }
            self.tip = numAmount * (Double(tipPercentage)/100)
        }
    }
    

    其次,如果当前视图结构创建(又名拥有)可观察对象,则始终使用@StateObject 而不是@ObservedObject。后者适用于在视图层次结构中的更高级别初始化并刚刚通过的对象。

    struct ContentView: View {
    
        //MARK: - PROPERTIES
        @StatedObject private var tipVM = TipViewModel()
    
        ...
    
            Text("£\(tipVM.tip)")
    

    【讨论】:

      猜你喜欢
      • 2021-03-11
      • 1970-01-01
      • 2021-07-06
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多