【问题标题】:How SwiftUI onChange modifier works?SwiftUI onChange 修饰符如何工作?
【发布时间】:2021-06-12 11:26:15
【问题描述】:

我动态填充了一个 SwiftUI 选择器。 Picker 工作正常。我想触发或监听选择器更改事件。假设如果用户选择一个项目,我将打印该值。我的 iOS 部署目标是 14,我发现 iOS 有一个内置函数 onChange 来检测这种监听器。我使用了那个修饰符但没有工作。 这是我的代码:

var body: some View {
    
    
    
    Picker( selection: $selectedStrength, label: Text("Status")) {
        
        ForEach(courseList, id: \.self) { item in
            
            Text(item.courseCode ?? "")
        }
    }
    .onChange(of:selectedStrength, perform: { _ in
        
        print("Value Changed!")
        
    })
    .pickerStyle(WheelPickerStyle())
    
}

【问题讨论】:

  • 你的意思是 print("Value Changed!") 不会在选择任何项目时被调用?
  • 是的,print("Value Changed!") 不工作

标签: ios swift swiftui picker


【解决方案1】:

试试下面的代码实现:

    struct ContentView: View {
        var colors = ["Red", "Green", "Blue", "Tartan"]
        @State private var selectedColor = "Red"
    
        var body: some View {
            VStack {
                Picker("Please choose a color", selection: $selectedColor) {
                    ForEach(colors, id: \.self) {
                        Text($0)
                    }
                }
                Text("You selected: \(selectedColor)")
            }
      

  }
}

【讨论】:

    【解决方案2】:

    我认为这是由于类型不匹配,Picker 选择类型和项目类型或 (!) 标记应该相同。一旦您按项目迭代但显示courseCode,这可能是错误的原因。

    尝试类似(未测试,因为提供的代码不是独立的且不可运行)

    Picker(selection: $selectedStrength, label: Text("Status")) {
        
        ForEach(courseList, id: \.self) { item in
            
           // assiming selectedStrength type and item.courseCode type is the same
            Text(item.courseCode ?? "").tag(item.courseCode)
        }
    }
    .onChange(of: selectedStrength, perform: { _ in
        
        print("Value Changed!")
        
    })
    

    【讨论】:

      【解决方案3】:

      总结:我调用了一个 REST API 并解析了数据,然后我尝试从这些数据中创建一个 SwiftUI Picker。

      解决方案:经过大量搜索,我找到了正确的解决方案。我直接从 Json 对象数据填充 Picker。我将这些数据转换为 SwiftUI 字符串数组并尝试了 onChange 函数,它现在可以工作了。

      我的代码:

      import SwiftUI
      
      struct TeacherCourseListParser: Decodable, Hashable{
          
          var totalStudent: Int?
          var courseName: String?
          var courseCode: String?
          var courseId: Int?
          var courseTeacherEnrollId: Int?
          
          
      }
      
      
          
      
      struct Test: View {
          
          @State var courseList = [TeacherCourseListParser]()
                
          @State private var selectedStrength = ""
          @State var courseCodeTempArray = [String]()
          
          var body: some View {
              
              VStack(spacing: 0){
                  
                  
                  Picker( selection: $selectedStrength, label: Text("Course Code")) {
                      
                      ForEach(courseCodeTempArray, id: \.self) {
                          
                         
                          Text($0)
                          
                          
                      }
                  }
                  .onChange(of: selectedStrength, perform: { _ in
                      
                      print("Value Changed!")
                  })
                  .pickerStyle(WheelPickerStyle())
                  
                  
                  
                  
                  
              }
              
          }
      

      这是我获取 JSON 对象的函数:

      func FetchTeacherCourseCode(){
              
              
              
              
              let token = UserDefaults.standard.string(forKey: "login_token")
            
              
              // create post request
                                                            
              guard let url = URL(string: Constant.mainServerUrl+Constant.getTeacherCourseList) else {
                  print("Invalid URL")
                  return
              }
              
              print(url)
              
              var request = URLRequest(url: url)
              request.httpMethod = "GET"
              // request.httpBody = jsonData
              request.allHTTPHeaderFields = [
                  "Content-Type": "application/json",
                  "Accept": "application/json",
                  "Authorization": "Bearer "+token!
              ]
              
              URLSession.shared.dataTask(with: request) {data, response, error in
                  if let data = data {
                      do {
                                                                                              
                          //-- Parse response according to the object
                          let detailedObjectFetcher = try! JSONDecoder().decode([TeacherCourseListParser].self, from: data)
                         
                          
                                                                          
                          DispatchQueue.main.async {
                              
                              for i in detailedObjectFetcher {
                                  
                                  // instead of populating Picker from JSON object directly I generated a string array                                                     
                                  courseCodeTempArray.append(i.courseCode ?? "")
                                  
                              }
                              
                             self.courseList = detailedObjectFetcher
                              showProgressBar = false
                              
                              
                          }
                          
                          
                          
                          
                      } catch DecodingError.keyNotFound(let key, let context) {
                          Swift.print("could not find key \(key) in JSON: \(context.debugDescription)")
                      } catch DecodingError.valueNotFound(let type, let context) {
                          Swift.print("could not find type \(type) in JSON: \(context.debugDescription)")
                      } catch DecodingError.typeMismatch(let type, let context) {
                          Swift.print("type mismatch for type \(type) in JSON: \(context.debugDescription)")
                      } catch DecodingError.dataCorrupted(let context) {
                          Swift.print("data found to be corrupted in JSON: \(context.debugDescription)")
                      } catch let error as NSError {
                          NSLog("Error in read(from:ofType:) domain= \(error.domain), description= \(error.localizedDescription)")
                      }
                  }
                  // print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
                  
              }.resume()
              
              
              
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2022-07-27
        • 2022-01-21
        • 2020-11-06
        • 2020-01-30
        • 1970-01-01
        • 2021-03-19
        • 2022-09-25
        • 2021-11-18
        • 1970-01-01
        相关资源
        最近更新 更多