Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 无法使用json数据填充UITableview_Ios_Json_Swift_Uitableview - Fatal编程技术网

Ios 无法使用json数据填充UITableview

Ios 无法使用json数据填充UITableview,ios,json,swift,uitableview,Ios,Json,Swift,Uitableview,我有一个本地json文件(你可以找到它) 我试图用这个json填充UITableView,我可以生成表 但我只能看到提到的标题,而不能看到这些标题单元格下的相应数据 我将在下面发布一些代码,如果有帮助的话,可以分享更多 enum ProfileViewModelItemType { case nameAndPicture case about case email case friend case attribute } protocol Profile

我有一个本地json文件(你可以找到它)

我试图用这个json填充
UITableView
,我可以生成表

但我只能看到提到的标题,而不能看到这些标题单元格下的相应数据

我将在下面发布一些代码,如果有帮助的话,可以分享更多

enum ProfileViewModelItemType {
    case nameAndPicture
    case about
    case email
    case friend
    case attribute
}

protocol ProfileViewModelItem {
    var type: ProfileViewModelItemType { get }
    var rowCount: Int { get }
    var sectionTitle: String  { get }
}

extension ProfileViewModelItem {
    var rowCount: Int {
        return 1
    }
}

class ProfileViewModelNameItem: ProfileViewModelItem {
    var type: ProfileViewModelItemType {
        return .nameAndPicture
    }

    var sectionTitle: String {
        return "Main Info"
    } 
}

class ProfileViewModelNameAndPictureItem: ProfileViewModelItem {
    var type: ProfileViewModelItemType {
        return .nameAndPicture
    }

    var sectionTitle: String {
        return "Main Info"
    }

    var rowCount: Int {
        return 1
    }

    var pictureUrl: String
    var name: String

    init(name: String , pictureUrl: String) {
        self.name = name
        self.pictureUrl = pictureUrl
    }
}

class ProfileViewModelAboutItem: ProfileViewModelItem {
    var type: ProfileViewModelItemType {
        return .about
    } 

    var sectionTitle: String {
        return "About"
    }
    var rowCount: Int {
        return 1
    }

    var about: String

    init(about: String) {
        self.about = about
    }
}

class ProfileViewModelEmailItem: ProfileViewModelItem {
    var type: ProfileViewModelItemType {
        return .email
    }

    var sectionTitle: String {
        return "Email"
    }
    var rowCount: Int {
        return 1
    }
    var email: String

    init(email: String) {
        self.email = email
    }
}

class ProfileViewModelAttributeItem: ProfileViewModelItem {
    var type: ProfileViewModelItemType {
        return .attribute
    }

    var sectionTitle: String {
        return "Attributes"
    }

    var rowCount: Int {
        return attributes.count
    }

    var attributes: [Attribute]

    init(attributes: [Attribute]) {
        self.attributes = attributes
    }
}

class ProfileViewModeFriendsItem: ProfileViewModelItem {
    var type: ProfileViewModelItemType {
        return .friend
    }

    var sectionTitle: String {
        return "Friends"
    }

    var rowCount: Int {
        return friends.count
    }

    var friends: [Friend]

    init(friends: [Friend]) {
        self.friends = friends
    }
}

class ProfileViewModel: NSObject {
    var items = [ProfileViewModelItem]()

    override init() {
        super.init()
        guard let data = dataFromFile("ServerData"), let profile =  Profile(data: data) else {
            return
        }

        if let name = profile.fullName, let pictureUrl = profile.pictureUrl {
            let nameAndPictureItem = ProfileViewModelNameAndPictureItem(name: name, pictureUrl: pictureUrl)
            items.append(nameAndPictureItem)
        }

        if let about = profile.about {
            let aboutItem = ProfileViewModelAboutItem(about: about)
            items.append(aboutItem)
        }

        if let email = profile.email {
            let dobItem = ProfileViewModelEmailItem(email: email)
            items.append(dobItem)
        }

        let attributes = profile.profileAttributes
        // we only need attributes item if attributes not empty
        if !attributes.isEmpty {
             let attributesItem = ProfileViewModelAttributeItem(attributes: attributes)
            items.append(attributesItem)
        }

        let friends = profile.friends
        // we only need friends item if friends not empty
        if !profile.friends.isEmpty {
            let friendsItem = ProfileViewModeFriendsItem(friends: friends)
             items.append(friendsItem)
        }
    }
}

extension ProfileViewModel:UITableViewDataSource {


    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return items[section].sectionTitle
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return items.count
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items[section].rowCount
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let item = items[indexPath.section]
        switch item.type {
        case .nameAndPicture:
            if let cell = tableView.dequeueReusableCell(withIdentifier: NameAndPictureCell.identifier, for: indexPath) as? NameAndPictureCell {
                cell.item = item
                return cell
            }
        case .about:
            if let cell = tableView.dequeueReusableCell(withIdentifier: AboutCell.identifier, for: indexPath) as? AboutCell {
                cell.item = item
               return cell
            }
        case .email:
            if let cell = tableView.dequeueReusableCell(withIdentifier: EmailCell.identifier, for: indexPath) as? EmailCell {
                cell.item = item
                return cell
            }
        case .friend:
            if let item = item as? ProfileViewModeFriendsItem, let cell = tableView.dequeueReusableCell(withIdentifier: FriendCell.identifier, for: indexPath) as? FriendCell {
                let friend = item.friends[indexPath.row]
                cell.item = friend
                return cell
            }
        case .attribute:
            if let item = item as? ProfileViewModelAttributeItem, let cell = tableView.dequeueReusableCell(withIdentifier: AttributesCell.identifier, for: indexPath) as? AttributesCell {
                cell.item = item.attributes[indexPath.row]
               return cell
            }
        }

        // return the default cell if none of above succeed
        return UITableViewCell()
    }
}


public func dataFromFile(_ filename: String) -> Data? {
    @objc class TestClass: NSObject { }

    let bundle = Bundle(for: TestClass.self)
    if let path = bundle.path(forResource: filename, ofType: "json") {
        return (try? Data(contentsOf: URL(fileURLWithPath: path)))
    }
    return nil
}

class Profile {
    var fullName: String?
    var pictureUrl: String?
    var email: String?
    var about: String?
    var friends = [Friend]()
    var profileAttributes = [Attribute]()

    init?(data: Data) {
        do {
             if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any],
                let body = json["data"] as? [String: Any] {
                self.fullName = body["fullName"] as? String
                self.pictureUrl = body["pictureUrl"] as? String
                self.about = body["about"] as? String
                self.email = body["email"] as? String

                if let friends = body["friends"] as? [[String: Any]] {
                    self.friends = friends.map { Friend(json: $0) }
                }

                if let profileAttributes = body["profileAttributes"] as? [[String: Any]] {
                    self.profileAttributes = profileAttributes.map { Attribute(json: $0) }
                }
            }
        } catch {
            print("Error deserializing JSON: \(error)")
            return nil
        }
    }
}

class Friend {
    var name: String?
    var pictureUrl: String?

    init(json: [String: Any]) {
        self.name = json["name"] as? String
        self.pictureUrl = json["pictureUrl"] as? String
    }
}

class Attribute {
    var key: String?
    var value: String?
    init(json: [String: Any]) {
        self.key = json["key"] as? String
        self.value = json["value"] as? String
    }
 }
表视图不仅应该有朋友的名字,还应该有资产中存在的图像

我还为所有不同类型的单元定义了自定义类,并对它们进行排队和注册

我们已经看了一个星期了,但仍然没有,如果有任何帮助,我们将不胜感激


我还提供了框架,并将所有标签、图像等作为子视图添加到表视图中,但运气不佳

我理解起来有点困难。首先,“我还提供了框架,并将所有标签、图像等作为子视图添加到表视图中”听起来是错误的。在UITableView上,您不需要调用
addSubview(…)
。您可以通过tableCell.contentView.addSubview(…)将UI元素添加到UITableViewCell,但即使如此,最好还是使用autolayout在interface builder中设计表视图单元格。如今,设置帧几乎毫无用处,因为自动布局已经永远存在。设置实际帧的唯一位置是
layoutSubviews()

第二,它不显示是因为您将行高设置为常量而不是UITableView.automaticDimension吗?也许您的单元格被设计为具有一定的高度,但您还没有告诉表视图它们具有该高度?我建议用谷歌搜索“使用自动布局自动调整表单元格大小”或使用表视图委托方法
…heightForRowAt indexPath:…

最后,看看您的代码,我建议您对JSON解析方法进行现代化:


类似于谷歌的“JSON和可编码的swift”

我理解起来有点困难。首先,“我还提供了框架,并将所有标签、图像等作为子视图添加到表视图中”听起来是错误的。在UITableView上,您不需要调用
addSubview(…)
。您可以通过tableCell.contentView.addSubview(…)将UI元素添加到UITableViewCell,但即使如此,最好还是使用autolayout在interface builder中设计表视图单元格。如今,设置帧几乎毫无用处,因为自动布局已经永远存在。设置实际帧的唯一位置是
layoutSubviews()

第二,它不显示是因为您将行高设置为常量而不是UITableView.automaticDimension吗?也许您的单元格被设计为具有一定的高度,但您还没有告诉表视图它们具有该高度?我建议用谷歌搜索“使用自动布局自动调整表单元格大小”或使用表视图委托方法
…heightForRowAt indexPath:…

最后,看看您的代码,我建议您对JSON解析方法进行现代化:


类似于google“JSON和Codable swift”

添加到表视图是一个绝望的措施,但没有成功,我在视图控制器中调用了自动维度,我没有使用interface builder构建,而是通过代码,我已经使用CGRECT将框架设置为整个屏幕。我觉得你在这方面没有太多经验。什么的框架?恐怕很难回答你的问题。您的问题似乎有两个部分:首先将JSON数据解析为模型,然后用这些模型填充表视图。可能使用自动调整表格单元格大小。我建议在raywenderlich.comhorseshoee7上做一些教程,是的,我对swift本身很陌生,我已经读过这篇文章,但在这个特殊的情况下帮不了我。尽管如此,我想我还是会尝试一下,然后再告诉你,添加到表视图是一个绝望的措施,但没有成功,我在视图控制器中调用了自动维度,我没有使用interface builder构建,而是全部通过代码,我已经使用CGRECT将框架设置为整个屏幕。我觉得你在这方面没有太多经验。什么的框架?恐怕很难回答你的问题。您的问题似乎有两个部分:首先将JSON数据解析为模型,然后用这些模型填充表视图。可能使用自动调整表格单元格大小。我建议在raywenderlich.comhorseshoee7上做一些教程,是的,我对swift本身很陌生,我已经读过这篇文章,但在这个特殊的情况下帮不了我。我想我还是会试试,然后再打给你