动态生成UITableView单元和头部

项目文件:

https://jumpshare.com/v/Otai3BBXYwfvyz8jb53k

(明智地看这些来看看项目的结构)

问题:

好的,所以我正在按照一个教程来创建一个带有标题和单元格内容的UITableView。

代码运行良好,现在我想扩展到该教程之外,并使用alamofire和SwiftyJSON动态加载该内容。

在教程中,使用的代码如下所示:

func getSectionsFromData() -> [Sections] {

    var sectionsArray = [Sections]()

    let animals = Sections(title: "Animals", objects: ["Cats", "Dogs", "Birds", "Lions"])


    sectionsArray.append(animals)

    return sectionsArray


}

我试图做的是:

Alamofire.request(.GET, url).validate().responseJSON { response in
        switch response.result {
        case .Success:
            if let value = response.result.value {
                let json = JSON(value)

                for (_, subJson) in json {
                    for (year, content) in subJson {
                        let title = year
                        let objects = content

                        sectionsArray.append(Sections(title: title, objects: objects))

                    }

                }
            }
        case .Failure(let error):
            print(error)
        }
    }

如果我打印出他们在控制台中显示的结果 - 所以我知道获取和循环JSON的作品。 然后我加入了

let title = year
let objects = content

sectionsArray.append(Sections(title: title, objects: objects))

但在这条线上:

sectionsArray.append(Sections(title:title,objects:objects))

我得到这个错误:

无法将类型'JSON'的值转换为期望的参数类型'[String]'

这是我正在使用的JSON:

 {"posts": [
 {
    "Category1": [
        "Post1cat1"
    ],
    "Category2": [
        "Post1cat2",
        "Post2cat2"
    ]
 }
 ]}

有人能帮我吗? 我可能会在错误的方向走,我想循环浏览JSON,并将类别显示为表格单元格中的标题和帖子。

编辑:1/29/2016

所以,我改变了循环:

for (_, subJson) in json {
                for (index, data) in subJson {
                    for (title, objects) in data {
                        sectionsArray.append(Sections(title: title, objects: objects.self.arrayValue.map { $0.string!}))


                    }

                }

            }

仍然没有运气。 当我添加一些打印(under:sectionsArray.append)来测试是否有数据时:

print("--")
print(title)
print(objects.self.arrayValue.map { $0.string!})
print(Sections(title: title, objects: objects.self.arrayValue.map { $0.string!}))

我在控制台中得到这个结果:

-

组别

[ “Post1cat1”]

部分(标题:“Category1”,项目:[“Post1cat1”])

-

产品组别

[“Post1cat2”,“Post2cat2”]

部分(标题:“Category2”,项目:[“Post1cat2”,“Post2cat2”])

其中显示信息存在,但是当我运行应用程序时,JSON仍然没有结果,只是最初定义的部分和上面的单元格。


在第二种解析方法中(编辑之后),您在最后一个循环中对数组进行迭代,因此您可以在那里创建数组并单独添加每个元素,如示例所示:

for (title, data) in subJson {
    var elements: [String] = []

    for (_, object) in data {
        if let stringELement = object.rawString() {
            elements.append(stringELement)
        }
    }

    sectionsArray.append(Sections(title: title, objects: elements))
}

或者如果您愿意,可以使用来自JSON对象的铸造原始数组,如下例所示:

for (_, subJson) in json["posts"] {
    for (title, data) in subJson {
        let optionalCastedObjects = data.arrayObject as? [String]
        let unwrappedObjects = optionalCastedObjects ?? []
        let section = Sections(title: title, objects: unwrappedObjects)

        sectionsArray.append(section)                        
    }
}

这应该解决上述编译问题。

但最后要记住,您正在同步getSectionsFromData方法中使用异步回调(在GET request )。 而且你总是会在该回调( clojure )的值添加新数据之前返回数组。 这会导致你永远不会显示你以这种方式获取的数据。

UPDATE

要做到这一点,你应该重构你的getSectionsFromData方法如下。

func getSectionsFromData(completion: ([Sections]) -> ()) {
    var sectionsArray = [Sections]()

    Alamofire.request(.GET, url).validate().responseJSON { response in
        switch response.result {
        case .Success:
            if let value = response.result.value {
                let json = JSON(value)

                for (_, subJson) in json["posts"] {
                    for (title, data) in subJson {
                        let optionalCastedObjects = data.arrayObject as? [String]
                        let unwrappedObjects = optionalCastedObjects ?? []
                        let section = Sections(title: title, objects: unwrappedObjects)

                        sectionsArray.append(section)
                    }
                }

                completion(sectionsArray)
            }
        case .Failure(let error):
            print(error)
        }
    }
}

和你的UITableViewController类中的相关部分。

var sections: [Sections] = []

override func viewDidLoad() {
    super.viewDidLoad()

    SectionsData().getSectionsFromData { [weak self](sections: [Sections]) -> () in
        self?.sections = sections
        self?.tableView.reloadData()
    }
}

您的第二个循环位于数组对象上,因此在该循环year是索引值, content是该索引处的对象。

你需要实现一个额外的循环来解决这个问题,即:

for (_, subJson) in json {
    for (index, data) in subJson {
        for (title, objects) in data {
            sectionsArray.append(Sections(title: title, objects: objects.arrayValue.map { $0.string!}))

        }

    }

}

从SwiftyJSON文档:

for (key,subJson):(String, JSON) in json {
   //Do something you want
}

这表明subJson的类型是JSON。 但是,第一个示例中的Sections构造函数是:

Sections(title: "Animals", objects: ["Cats", "Dogs", "Birds", "Lions"])

在第二个示例中,您将其称为:

Sections(title: title, objects: objects)

除非你改变了构造函数,否则它会希望objects是一个字符串数组,而不是JSON。 这就是为什么你得到一个错误,说Swift不能将JSON转换为String。 在你的情况下, objects JSON实际上是一个字符串数组,所以你需要使用像这样的东西:

Sections(title: title, objects: objects.arrayValue.map { $0.string!})
链接地址: http://www.djcxy.com/p/31779.html

上一篇: Dynamically Generate UITableView Cells and Headrs

下一篇: How to add draggable icon with navigation drawer