簡體   English   中英

SwiftUI - 顯示符合協議的元素並為元素使用 == 的視圖

[英]SwiftUI - View showing Elements conforming to a Protocol and and using == for the Elements

我需要在視圖中顯示符合通用協議的不同結構的 arrays。
正如SwiftUI 中所建議的 - 查看顯示符合協議的元素和 ForEach 在它們之上我嘗試過這樣 - 它工作正常!

現在我需要檢查數組的元素是否相等。
讓協議符合Equatable不會編譯 -
它得到錯誤: Protocol 'Suggest' can only be used as a generic constraint because it has Self or associated type requirements

//protocol Suggest :Equatable {
protocol Suggest  {
  var desc: String { get }
}

struct Person : Suggest {
  var surname : String
  var name: String
  
  var id: String { return name }
  var desc: String { return name }
}

struct Book : Suggest {
  var titel : String
  var abstact : String
  
  var id: String { return titel }
  var desc: String { return titel }
}


let books = [ Book(titel: "book 1", abstact: "abstract1"),
              Book(titel: "book 2", abstact: "abstract2")
            ]

let persons = [ Person(surname: "John", name: "Doe"),
                Person(surname: "Susan", name: "Smith"),
                Person(surname: "Frank", name: "Miller")
              ]


struct ContentView: View {
  var body: some View {
    VStack {
      SuggestList(list: books)
      SuggestList(list: persons)
    }
  }
}

struct SuggestList: View {
  var list : [Suggest]
// this line does not compile, if Suggest conforms to Equitable
// "Protocol 'Suggest' can only be used as a generic constraint because it has Self or associated type requirements" 
  
  var body: some View {
    List(list.indices, id: \.self) { index in
      Text(list[index].desc)
//        .onTapGesture {
//          if list.contains(list[index]){print ("hello")}
//        }
    }
  }
}

您需要使用<SuggestType: Suggest>並讓Suggest協議Equatable ,然后在PersonBook中使用和定義==


struct ContentView: View {
    var body: some View {
        VStack {
            SuggestList(list: books)
            SuggestList(list: persons)
        }
    }
}

protocol Suggest: Equatable  {
    var desc: String { get }
}

struct Person: Suggest {
    
    var surname: String
    var name: String
    
    var id: String { return name }
    var desc: String { return name }
    
    
    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.name == rhs.name
    }
    
}

struct Book: Suggest {
    
    var titel: String
    var abstact: String
    
    var id: String { return titel }
    var desc: String { return titel }
    
    static func == (lhs: Book, rhs: Book) -> Bool {
        return lhs.titel == rhs.titel
    }
    
    
}



let persons = [Person(surname: "John", name: "Doe"),
               Person(surname: "Susan", name: "Smith"),
               Person(surname: "Frank", name: "Miller")]


let books = [Book(titel: "book 1", abstact: "abstract1"),
             Book(titel: "book 2", abstact: "abstract2")]




struct SuggestList<SuggestType: Suggest>: View {
    
    var list : [SuggestType]

    
    var body: some View {
        List(list.indices, id: \.self) { index in
            Text(list[index].desc)
                .onTapGesture {
                    if list.contains(list[index]){ print(list[index].desc) }
                }
        }
    }
}

這個答案屬於評論部分的問題! 關於Equatable function。

If you do not define Equatable function explicitly, then Xcode would take care itself if it can infer it by itself, some times in complex struct it will ask you to show it when instance of your struct are equal, but when you define Equatable function explicitly Xcode 將應用您的自定義規則,例如,我創建了 2 種類型的人,在第一個PersonV1 中我們沒有為它定義== ,但在第二個PersonV2 中我們確實定義了! 所以 Xcode 將在PersonV2中取所有同名的人,即使他們有不同的surname 試試這個代碼以獲得更真實的測試示例。 並且PersonV2姓氏的任何更新都不會發生,因為它不計入確定PersonV2的 2 個實例是否相等! 初始化PersonV2的實例后,姓氏將不再可更新。 您可以嘗試更新,但它不會應用,因為如果此實例是否相同,則不予考慮!

注意:我們可以使PersonV2相等 function 也可以使用此代碼對姓氏更改做出反應,但我認為您只想使用問題中的名稱

static func == (lhs: PersonV2, rhs: PersonV2) -> Bool {
    return lhs.name == rhs.name && lhs.surname == rhs.surname
}



struct ContentView: View {

    @State private var person1: PersonV1 = PersonV1(surname: "Frank", name: "Miller")
    @State private var person2: PersonV2 = PersonV2(surname: "John", name: "Doe")

    var body: some View {
        
        VStack(spacing: 50.0) {
        
        VStack(spacing: 20.0) {

            Button("update name of person1") { person1.name += " updated!" }
            Button("update surname of person1") { person1.surname += " updated!" }

        }
        .padding()
        .background(Color.yellow)
        .onChange(of: person1) { newValue in print("onChange for person1:", newValue) }
        
        
        
        
        VStack(spacing: 20.0) {

            Button("update name of person2") { person2.name += " updated!" }
            Button("update surname of person2") { person2.surname += " updated!" }

        }
        .padding()
        .background(Color.red)
        .onChange(of: person2) { newValue in print("onChange for person2:", newValue) }
        
        }
        
    }
}

protocol Suggest: Equatable  {
    var desc: String { get }
}



struct PersonV1: Suggest {
    
    var surname: String
    var name: String
    
    var id: String { return name }
    var desc: String { return name }
   
}


struct PersonV2: Suggest {
    
    var surname: String
    var name: String
    
    var id: String { return name }
    var desc: String { return name }

    static func == (lhs: PersonV2, rhs: PersonV2) -> Bool {
        return lhs.name == rhs.name
    }
    
}

暫無
暫無

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

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