【问题标题】:Segue in UITableView with multiple sections, each containing objects filtered from a single array在 UITableView 中使用多个部分进行 Segue,每个部分都包含从单个数组中过滤的对象
【发布时间】:2015-04-23 17:36:29
【问题描述】:

我是一个初学者,显然不适合我,我无法在网上找到答案。

我有一个UITableViewController 和一个UITableView,显示存储在一个数组中的自定义对象。我没有在所述 TableView 的一个部分中显示数组的所有对象:TableView 有多个部分,每个部分包含我的对象数组的过滤部分(我过滤自定义对象数组检查对象类别属性等于我在类别数组中指定的类别)。

这种过滤并在不同部分显示单个数组工作正常(我知道这可能不优雅,因为我说过我是编码初学者,我绝对需要使用单个数组,而不创建与过滤结果相对应的其他数组),但为了更好地理解我的问题,我认为最好展示我所做的,所以这是我代码的 TableView 部分:

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return myCategoriesArray.count
    }

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        for (var i = 0; i <= section; i++){
            if section == i {
                for eachCategory in myCategoriesArray {
                    return myObjectsArray!.filter() { $0.objectCategoryProperty == myCategoriesArray[i] }.count
                }
            }
        }
    // ...
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {   
        var cell = tableView.dequeueReusableCellWithIdentifier("objectCell", forIndexPath: indexPath) as UITableViewCell
        for (var i = 0; i <= indexPath.section; i++){
            if indexPath.section == i {
                for eachCategory in myCategoriesArray {
                    cell.textLabel?.text = myObjectsArray!.filter() { $0.objectCategoryProperty == myCategoriesArray[i] }[indexPath.row].nameProperty
                    return cell
                }
            }
        }
    // ...
}

这在某种意义上是有效的,因为我有 UITableViewController 显示我的所有对象,但按类别在单独的部分中过滤。

当我选择一个单元格并显示详细视图时,我的问题是转场。

这是我的prepareForSegue 方法:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        var nextVC = segue.destinationViewController as MyNextViewController
        if let indexPath = tableView.indexPathForSelectedRow() {
            let selected = myObjectsArray![indexPath.row]
            nextVC.passedObject = selected
        }
    }
}

我相信你们中的许多人已经看到了我的问题:我传递给下一个 ViewController 的对象是在自定义对象数组中使用索引 [indexPath.row] 选择的,但 indexPath.row 开始于每个部分都为 0,所以当我选择一个对象时,它在 TableView 中的索引不等于自定义对象数组中的索引,这意味着我传递了错误的对象。

现在,我被卡住了,因为我看不到将正确(意思是,选定的)对象传递给下一个视图控制器的方法,同时 保留了我只使用单个数组的事实。

我想为每个对象添加一个 objectIDString 属性,并在每次选择单元格时设置一个 var currentSelectedObjectIDString,并尝试将 objectIDString 属性与 currentSelectedObjectIDString 匹配的对象传递给下一个视图控制器,但在我缺乏经验的人看来,这似乎是个坏主意,而且我实际上不确定如何才能做到这一点,即使我想这样做(也许实施didSelectRowAtIndexPath:,但我无法让它发挥作用)。

任何帮助都将不胜感激,我已经坚持了很长时间,我开始质疑 a)我的理智 b)我在项目中做出的每一个决定(意思是,所有对象的单个数组部分过滤),但我已经非常投入,我真的不想重新开始。

谢谢,

切萨雷

附:我希望我的问题很清楚,英语不是我的主要语言...抱歉任何错误!

【问题讨论】:

    标签: iphone arrays uitableview swift segue


    【解决方案1】:

    我建议你使用 NSFetchedResultsController。这个类有一个属性sectionNameKeyPath。在此属性中,您可以设置您的类别,并且您不需要在每个 numberOfSection 和 numberOfRows 中重复进行更多迭代。

    像这样:

        let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: "event.startDate", cacheName: nil)
    

    在我的情况下,我需要按 event.startDate 过滤数据。

    我不知道你是否在使用核心数据,但如果你在使用,这是更好的方法。

    我会为你揭发! 一开始 NSFetchedResultsController 很复杂,但它非常非常有用。不要害怕。

    我不完全了解您的模型和数据。在这种情况下,我将向您展示我的所有者样本。

    请在以下链接中查看我的问题: Sectioning TableView and rows with Core Data Swift

    在此链接中,请参阅我的问题,在底部我将解释完整的解决方案以及其他答案。

    如果你不清楚,请和我谈谈:.)

    【讨论】:

    • 非常感谢您花时间回答和帮助我!在我的项目早期,我决定不使用 Core Data,因为我认为它太复杂了,但我开始意识到如果我花几天时间学习它可能会更好:我已经花了一整天的时间尝试解决这个问题(我离线,之前没有看到你的答案),我想我已经整理了一堆可行的解决方法(如果是这样,我会发布它们),但我担心它很容易被打破.我正在为您的答案和“Sectioning TableView and rows w/Core Data Swift”添加书签并开始研究它,再次感谢!
    • 很高兴与您分享一些东西!我正在学习 swift 和英语,微笑。当我开始使用 swift 时,我避免使用核心数据,但是当我来到这一点时,就像你一样,类别或部分,我需要使用它。这篇文章,对我帮助很大。我会和你分享:rshankar.com/…
    • 再次感谢您的好意和分享这篇文章。我从一开始就知道,我正在开发的应用程序可能有大量数据,这些数据将以不同的方式呈现,并且需要 iCloud 同步,理想情况下是使用 Core Data 开发的,但我真的很想潜心开发,在开始之前我没有耐心学习,现在我为此付出了代价。再次感谢,如果可以的话,我会在将来为您提供更多关于此的问题!祝你好运,切萨雷
    • 嗨,切萨雷!恭喜!你找到了解决办法!祝你好运!跟我一起算,如果我能帮上忙!
    • 再次感谢,我实际上并不认为它是一个真正的解决方案,它太过分了,所以我打算按照你之前发给我的文章走 Core Data 的路。但是我发现的解决方法虽然不是很漂亮,但让我可以在学习 Core Data 的同时暂时推进开发,所以我很高兴这一天。请让我知道是否有机会回报我!
    【解决方案2】:

    我花了一整天的时间想办法解决我自己的上述问题,我想我终于找到了一个可行的解决方法。 我的前提和免责声明是,这是一堆黑客,我发布这个只是为了以防将来可能对我的情况有所帮助,但显然处理这种情况的方法是 Core Data,正如 Weles 所建议的那样回答,而不是我所做的。

    以下是我为获取多组件 UITableView 所做的简要说明,其中所有数据来自单个自定义对象数组,每个组件中由不同值过滤,以将所选对象传递给详细信息查看何时选择了一个单元格。

    1) 我在所有 customObjects 中添加了一个 objectID:字符串计算属性(当前日期 + 随机数)。

    2) 我添加了一个 var currentSelectedObjectID : String?在我的 TableViewController 中。

    3) 我对UITableViewCell 进行了子类化,创建了一个CustomTableViewCell 类,它只向普通类添加了一个var selectedCellID : String?,然后我更改了我的cellForRowAtIndexPath 以返回一个CustomTableViewCell 而不是UITableViewCell。在这个方法内部,在返回单元格之前,我还将单元格的属性 selectedCellID 设置为等于当前对象的 objectID。我还必须将 Storyboard 中单元格的类从 UITableViewCell 更改为 CustomTableViewCell。

    4) 在 Storyboard 中,我将单元格中的 segue 移至由 Xcode 自动创建的 detailViewController,并将自定义 StoryboardID 设置为 detailViewController ("detailVC"),

    5) 在 TableViewController 的didSelectRowAtIndexPath 内部,我完成了在prepareForSegue 中尝试做的所有工作,但是以不同的方式(不是转场,self.navigationController?.pushViewController)。代码如下:

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    
    let indexPath = tableView.indexPathForSelectedRow();
    
    let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as CustomTableViewCell!;
    
    self.currentlySelectedObjectID = currentCell.selectedCellID
    
    // detailViewController instance
    var detailVC = self.storyboard?.instantiateViewControllerWithIdentifier("detailVC") as MyDetailViewController
    
    // I filter my objects array to "extract" the object with the objectID property equal to the currentlySelectedObjectID property (which is equal to the currentCell.selectedCellID, as set above). This array must have only 1 value. If so, I set the property passedCustomObject that I have in my detailViewController to the same object selected.
    if (myObjectsArray!.filter() { $0.objectID == self.currentlySelectedObjectID }).count == 1 {
        detailVC.passedCustomObject = (myObjectsArray!.filter() { $0.objectID == self.currentlySelectedObjectID })[0]
    
    } else {
        println("Error passing the object selected in the TableView to the DetailView")
    }
    
    // I push the detailViewController on top of the stack
    self.navigationController?.pushViewController(detailVC, animated: true)
    }
    

    我认为一个体面的程序员(我不是一个,但我希望有一天能成为一个)看到我所做的事情,很有可能会晕倒。 再说一次,我认为任何人都不应该这样做,如果您遇到同样的情况,请直接访问 Core Data:我花了一天时间在这上面,很有可能在三到四天内我就可以让 Core Data 正常工作。 但是,尽管这样被破解且效率低下,但它仍然有效……我测试了多次。所以,花了这么多时间,在网上找不到有用的类似以前的答案,我想发布我的。

    别这样,我真怕这容易坏! :)

    我仍然期待其他答案,从我的无数错误中吸取教训!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多