簡體   English   中英

SwiftUI onChange 修飾符如何工作?

[英]How SwiftUI onChange modifier works?

我動態填充了 SwiftUI Picker。 Picker 工作正常。 我想觸發或監聽選擇器更改事件。 假設如果用戶 select 是一個項目,我將打印該值。 我的 iOS 部署目標是 14,我發現 iOS 有一個內置的 function 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())
    
}

嘗試下面的代碼來實現:

    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)")
            }
      

  }
}

我認為這是由於類型不匹配,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!")
    
})

總結:我調用了 REST API 並解析數據,然后我嘗試從這些數據中創建一個 SwiftUI Picker。

解決方案:經過大量搜索,我找到了正確的解決方案。 我直接從 Json object 數據填充選擇器。 我將這些數據轉換為 SwiftUI 字符串數組並嘗試onChange function,它現在可以工作了。

我的代碼:

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())
            
            
            
            
            
        }
        
    }

這是 function 我如何獲取 JSON object:

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()
        
        
        
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM