【问题标题】:Dynamically Generate UITableView Cells and Headrs动态生成表格视图单元格和标题
【发布时间】:2016-05-06 15:31:28
【问题描述】:

项目文件:

https://jumpshare.com/v/Otai3BBXYwfvyz8jb53k

(最好查看这些以了解项目结构)

问题:

好的,所以我正在关注tutorial,它创建了一个带有标题和单元格内容的 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 并将类别显示为标题,并将帖子显示在表格的单元格中。

编辑:2016 年 1 月 29 日

所以,我将循环更改为:

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


                    }

                }

            }

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

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

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

--

类别 1

["Post1cat1"]

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

--

类别2

["Post1cat2", "Post2cat2"]

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

这表明信息在那里,但是当我运行应用程序时,仍然没有结果来自他的 JSON,只是最初定义的部分和上面的单元格。

【问题讨论】:

    标签: json swift uitableview alamofire swifty-json


    【解决方案1】:

    来自 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!})
    

    【讨论】:

    • soo 我试过了:sectionsArray.append(Sections(title: title, objects: objects.arrayValue.map { $0.string!})) 并运行了模拟器 - 所显示的只是动物细胞没有任何新项目,都没有错误
    • 如果有帮助,我已经添加了项目文件。
    • 我在工作,那个网站被屏蔽了。我回家后看看。您是否使用调试器单步执行代码并查看调用 append 的频率?
    【解决方案2】:

    您的第二个循环位于数组对象上,因此在该循环中,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!}))
    
            }
    
        }
    
    }
    

    【讨论】:

    • 所以,我把它加进去了。什么也没发生。在我打印 (sectionsArray) 时的所有循环中,我得到: [sections.Sections(headings: "Animals", items: ["Cats", "Dogs", "Birds", "Lions"])] no new items
    • 您是否处理过项目文件?你能把文件放上来下载吗?
    • 另外,当我将您的sections.array(...) 更改为基本的:sectionsArray.append(Sections(title: "test", objects: ["one","two"] )) 使用硬编码值,它也不起作用。 :S
    【解决方案3】:

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

    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) 中的值添加新数据之前返回数组。这将导致您永远不会显示以这种方式获取的数据。

    更新

    为此,您应该重构您的 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()
        }
    }
    

    【讨论】:

    • 问题不在于解析,它工作正常。问题是让它们显示在他的表格视图中。它没有更新。
    • 请尝试更新标题之后的部分。 Works for me :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多