【问题标题】:SwiftUI List only using first item of given arraySwiftUI List 仅使用给定数组的第一项
【发布时间】:2020-06-20 05:32:29
【问题描述】:

我在下面有一个简单的视图来显示用户的所有联系人:

struct AllContactsView: View {
    static let withState: some View = AllContactsView().environmentObject(AllContactsProvider())
    @EnvironmentObject var contactsProvider: AllContactsProvider
    let title: UserListType = .selectInvitees

    var body: some View {
        List(self.contactsProvider.invitees) { invite in
            self.row(for: invite)
        }
        .navigationBarTitle(Text(self.title.rawValue))
        .onAppear(perform: self.contactsProvider.fetch)
    }

    func row(for invite: Invitee) -> some View {
        // everything below is only printed out once!
        print(self.contactsProvider.invitees.prettyPrinted) // shows correct array of contacts
        print(type(of: self.contactsProvider.invitees)) // this is indeed an array
        print(invite) // prints out the first item in the array (which is expected on first pass)
        return UserRow(invitee: invite)
    }
}

我正在操作CNContacts 的数组,我得到这样的被邀请者数组,这是我试图在我的列表中显示的内容:

self?.invitees = contacts.asSimpleContacts.map({ $0.asUser.asInvitee })

使用以下支持功能和扩展:

// Contact Value simplified so we can pass it around as a value type.
public struct SimpleContact: Hashable, Codable {
    let firstName: String
    let lastName: String
    let emails: [String]
    let phoneNumbers: [PhoneNumber]

    var fullName: String { "\(self.firstName) \(self.lastName)" }

    var asUser: User {
        User(
            id: Constants.unsavedID,
            username: self.fullName,
            picURL: "al",
            email: self.emails.first ?? "",
            phone: self.phoneNumbers.first ?? "",
            created: Date().timeIntervalSince1970
        )
    }
}


extension CNContact {
    /// Returns the `SimpleContact` representation of `self`
    var asSimpleContact: SimpleContact {
        SimpleContact(
            firstName: self.givenName,
            lastName: self.familyName,
            emails: self.emailAddresses.map({ String($0.value) }),
            phoneNumbers: self.phoneNumbers.map({ Authentication.sanitize(phoneNo: $0.value.stringValue) })
        )
    }
}

extension Array where Element == CNContact {
    /// Returns the `SimpleContact` mapping of `self`
    var asSimpleContacts: [SimpleContact] { self.map({ $0.asSimpleContact }) }
}

public struct User: Hashable, Codable, Identifiable {
    public let id: String
    let username: String
    let picURL: String
    let email: String
    let phone: String
    let created: Double

    var asInvitee: Invitee { Invitee(user: self, isGoing: false) }
}

联系人填充到self.contactsProvider.invitees 中,正如预期的self.contactsProvider.fetch() 之后。但是,SwiftUI 显示的是 self.contactsProvider.invitees.countself.contactsProvider.invitees.first 实例,而不是每个联系人。我已经将下面的方法与其他在线示例进行了比较,似乎无法找到我出错的地方。我已经确定问题出在联系人操作的某个地方 - 当我提供一个模拟的受邀者数组时,一切都按预期工作,尽管在没有模拟的情况下按预期编译和运行,并且打印和调试没有显示任何内容。

任何帮助将不胜感激。

【问题讨论】:

    标签: ios swiftui contacts cncontactstore xcode11.3


    【解决方案1】:

    我刚碰到这个问题,回答得更清楚一点:

    SwiftUI 列表中的每一行都应使用唯一的 ID 生成。

    如果您使用 List() 函数创建视图,请确保您指定了 id

    struct MenuView: View {
    var body: some View {
        VStack {
            Section(header: MenuSectionHeader()) {
                //item.sku is the unique identifier for the row
                List(Menu.allItems, id:\.sku) { item in 
                    MenuItemRow(item)
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      对于遇到类似情况的任何人来说,问题在于我用来实例化对象的 ID 不是唯一的。很好奇,如果发生该错误,这将是预期的行为,但事实就是如此。

      【讨论】:

      • 谢谢,这也是我的问题
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多