在具有多个部分的 UITableView 中进行 Segue,每个部分包含从单个数组中过滤的对象
Segue in UITableView with multiple sections, each containing objects filtered from a single array
我是初学者,显然不在我的行列,而且我无法在网上找到答案。
我有一个 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() { [=10=].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() { [=10=].objectCategoryProperty == myCategoriesArray[i] }[indexPath.row].nameProperty
return cell
}
}
}
// ...
}
这在某种意义上是有效的,因为我有 UITableViewController
显示我的所有对象,但按类别在单独的部分中过滤。
我的问题是当我 select 一个单元格并显示详细视图时的 segue。
这是我的 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 的对象是 select 在自定义对象数组中使用 as索引 [indexPath.row],但是每个部分的 indexPath.row 从 0 开始,所以当我 select 一个对象时,它在 TableView 中的索引不等于自定义对象数组中的索引,这意味着我传递了错误的对象。
现在,我被卡住了,因为我看不到一种方法可以将正确的(意思是 selected)对象传递给下一个视图控制器,同时 保留我我只使用一个数组。
我正在考虑向每个对象添加一个 objectIDString 属性 和一个单独的 var currentlySelectedObjectIDString ,每次单元格被 selected 并尝试传递给下一个视图使用与 currentlySelectedObjectIDString 匹配的 objectIDString 属性 来控制对象,但在我缺乏经验的眼中这看起来是个坏主意,实际上我不确定如何实现它,即使我想(也许实现 didSelectRowAtIndexPath:
, 但我没能使它工作)。
任何帮助将不胜感激,我一直坚持这一点我开始质疑 a) 我的理智 b) 到目前为止我在项目中做出的每一个决定(意思是,所有对象的单个数组这是按部分过滤的),但我已经对它投入了太多,我真的不想重新开始。
谢谢,
切萨雷
P.S。我希望我的问题很清楚,英语不是我的主要语言...对于任何错误,我们深表歉意!
我建议你使用 NSFetchedResultsController。此 class 有一个 属性 sectionNameKeyPath。在此 属性 中,您可以设置类别,并且不需要在每个 numberOfSection 和 numberOfRows 中重复进行更多迭代。
像这样:
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: "event.startDate", cacheName: nil)
在我的例子中,我需要通过 event.startDate 过滤数据。
我不知道你是不是在使用核心数据,但如果你在使用,这是更好的方法。
我给你曝光!
NSFetchedResultsController 乍一看很复杂,但它非常有用。不要害怕。
我不太清楚你的模型和数据。在这种情况下,我将向您展示我的所有者示例。
请看下面我的问题link:
Sectioning TableView and rows with Core Data Swift
在此link中,查看我的问题,在底部我将解释完整的解决方案以及其他答案。
如果您不清楚,请与我交谈:.)
我花了一整天的时间试图找出一种方法来解决我自己的上述问题,我想我终于找到了解决方法。
我的前提和免责声明是,这是一堆 hack,我 post 这只是为了以防万一这可能会帮助将来遇到我这种情况的人,但显然处理这种情况的方法是核心数据,因为Weles 的回答建议的,不是我做的。
这里简要介绍了我为获得多组件 UITableView 所做的工作,其中所有数据都来自单个自定义对象数组,该数组在每个组件中由不同的值过滤,以将所选对象传递给选择单元格时的详细视图。
1) 我向我所有的 customObjects 添加了一个 objectID : String computed 属性 (current date + random number).
2) 我添加了一个 var currentlySelectedObjectID : String?在我的 TableViewController 中。
3) 我子classed UITableViewCell
,创建了一个 CustomTableViewCell class 只添加到正常 class 一个 var selectedCellID : String?,然后我改变了我的 cellForRowAtIndexPath
到 return CustomTableViewCell 而不是 UITableViewCell
。在此方法中,在 return 单元格之前,我还将单元格的 属性 selectedCellID 设置为等于当前对象的 objectID。我还必须将 Storyboard 中单元格的 class 从 UITableViewCell 更改为 CustomTableViewCell。
4) 在 Storyboard 中,我删除了从单元格到由 Xcode 自动创建的 detailViewController 的 segue,并将自定义 StoryboardID 设置为 detailViewController ("detailVC"),
5) 在 TableViewController 的 didSelectRowAtIndexPath
中,我完成了之前在 prepareForSegue
中尝试做的所有工作,但方式不同(不是 segue,而是 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() { [=10=].objectID == self.currentlySelectedObjectID }).count == 1 {
detailVC.passedCustomObject = (myObjectsArray!.filter() { [=10=].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 工作了。
但是,尽管如此被黑且效率低下,它仍然有效……我测试了多次。因此,在花了很多时间并且没有在网上找到有用的类似以前的答案之后,我想 post 我的。
不要这样,我真的很怕这很容易坏! :)
我仍然期待其他答案,从我无数的错误中吸取教训!
我是初学者,显然不在我的行列,而且我无法在网上找到答案。
我有一个 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() { [=10=].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() { [=10=].objectCategoryProperty == myCategoriesArray[i] }[indexPath.row].nameProperty
return cell
}
}
}
// ...
}
这在某种意义上是有效的,因为我有 UITableViewController
显示我的所有对象,但按类别在单独的部分中过滤。
我的问题是当我 select 一个单元格并显示详细视图时的 segue。
这是我的 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 的对象是 select 在自定义对象数组中使用 as索引 [indexPath.row],但是每个部分的 indexPath.row 从 0 开始,所以当我 select 一个对象时,它在 TableView 中的索引不等于自定义对象数组中的索引,这意味着我传递了错误的对象。
现在,我被卡住了,因为我看不到一种方法可以将正确的(意思是 selected)对象传递给下一个视图控制器,同时 保留我我只使用一个数组。
我正在考虑向每个对象添加一个 objectIDString 属性 和一个单独的 var currentlySelectedObjectIDString ,每次单元格被 selected 并尝试传递给下一个视图使用与 currentlySelectedObjectIDString 匹配的 objectIDString 属性 来控制对象,但在我缺乏经验的眼中这看起来是个坏主意,实际上我不确定如何实现它,即使我想(也许实现 didSelectRowAtIndexPath:
, 但我没能使它工作)。
任何帮助将不胜感激,我一直坚持这一点我开始质疑 a) 我的理智 b) 到目前为止我在项目中做出的每一个决定(意思是,所有对象的单个数组这是按部分过滤的),但我已经对它投入了太多,我真的不想重新开始。
谢谢,
切萨雷
P.S。我希望我的问题很清楚,英语不是我的主要语言...对于任何错误,我们深表歉意!
我建议你使用 NSFetchedResultsController。此 class 有一个 属性 sectionNameKeyPath。在此 属性 中,您可以设置类别,并且不需要在每个 numberOfSection 和 numberOfRows 中重复进行更多迭代。
像这样:
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: "event.startDate", cacheName: nil)
在我的例子中,我需要通过 event.startDate 过滤数据。
我不知道你是不是在使用核心数据,但如果你在使用,这是更好的方法。
我给你曝光! NSFetchedResultsController 乍一看很复杂,但它非常有用。不要害怕。
我不太清楚你的模型和数据。在这种情况下,我将向您展示我的所有者示例。
请看下面我的问题link: Sectioning TableView and rows with Core Data Swift
在此link中,查看我的问题,在底部我将解释完整的解决方案以及其他答案。
如果您不清楚,请与我交谈:.)
我花了一整天的时间试图找出一种方法来解决我自己的上述问题,我想我终于找到了解决方法。 我的前提和免责声明是,这是一堆 hack,我 post 这只是为了以防万一这可能会帮助将来遇到我这种情况的人,但显然处理这种情况的方法是核心数据,因为Weles 的回答建议的,不是我做的。
这里简要介绍了我为获得多组件 UITableView 所做的工作,其中所有数据都来自单个自定义对象数组,该数组在每个组件中由不同的值过滤,以将所选对象传递给选择单元格时的详细视图。
1) 我向我所有的 customObjects 添加了一个 objectID : String computed 属性 (current date + random number).
2) 我添加了一个 var currentlySelectedObjectID : String?在我的 TableViewController 中。
3) 我子classed UITableViewCell
,创建了一个 CustomTableViewCell class 只添加到正常 class 一个 var selectedCellID : String?,然后我改变了我的 cellForRowAtIndexPath
到 return CustomTableViewCell 而不是 UITableViewCell
。在此方法中,在 return 单元格之前,我还将单元格的 属性 selectedCellID 设置为等于当前对象的 objectID。我还必须将 Storyboard 中单元格的 class 从 UITableViewCell 更改为 CustomTableViewCell。
4) 在 Storyboard 中,我删除了从单元格到由 Xcode 自动创建的 detailViewController 的 segue,并将自定义 StoryboardID 设置为 detailViewController ("detailVC"),
5) 在 TableViewController 的 didSelectRowAtIndexPath
中,我完成了之前在 prepareForSegue
中尝试做的所有工作,但方式不同(不是 segue,而是 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() { [=10=].objectID == self.currentlySelectedObjectID }).count == 1 {
detailVC.passedCustomObject = (myObjectsArray!.filter() { [=10=].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 工作了。 但是,尽管如此被黑且效率低下,它仍然有效……我测试了多次。因此,在花了很多时间并且没有在网上找到有用的类似以前的答案之后,我想 post 我的。
不要这样,我真的很怕这很容易坏! :)
我仍然期待其他答案,从我无数的错误中吸取教训!