searchDisplayController、UITableView、Core Data 和 Swift

Posted

技术标签:

【中文标题】searchDisplayController、UITableView、Core Data 和 Swift【英文标题】:searchDisplayController, UITableView, Core Data and Swift 【发布时间】:2014-06-30 12:13:51 【问题描述】:

尝试使用searchDisplayController 在表中搜索。配置数据过滤,搜索对话框有效。现在我想使用方法prepareForSegue 将当前值indexPath 发送到新的UIViewController

import UIKit
import CoreData

class MainTableViewController: UITableViewController 

var results:AddrBook[]=[]
var searchResults:AddrBook[]=[]

init(style: UITableViewStyle) 
    super.init(style: style)


init(coder aDecoder: NSCoder!) 
    super.init(coder: aDecoder)


override func viewDidLoad() 
    super.viewDidLoad()



override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()


override func viewDidAppear(animated: Bool) 
    let request = NSFetchRequest(entityName: "Person")
    request.returnsObjectsAsFaults = false
    let appDelegate:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
    let context:NSManagedObjectContext = appDelegate.managedObjectContext
    results  = context.executeFetchRequest(request, error: nil) as AddrBook[]
    self.tableView.reloadData()


override func numberOfSectionsInTableView(tableView: UITableView?) -> Int 
    return 1


override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int 
    if tableView == self.searchDisplayController.searchResultsTableView 
        return searchResults.count
     else 
        return results.count
    


override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell! 
    var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell

    if !cell 
        cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
    

    if tableView == self.searchDisplayController.searchResultsTableView 
        cell!.textLabel.text = searchResults[indexPath.row].lastname + " " + searchResults[indexPath.row].firstname
        cell!.detailTextLabel.text = searchResults[indexPath.row].phonenumber
     else 
        cell!.textLabel.text = results[indexPath.row].lastname + " " + results[indexPath.row].firstname
        cell!.detailTextLabel.text = results[indexPath.row].phonenumber
    



    return cell


override func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) 
    if tableView == self.searchDisplayController.searchResultsTableView 
        self.performSegueWithIdentifier("editPerson", sender : self)
    


override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject?) 

    var indexPath = NSIndexPath()
    if self.tableView == self.searchDisplayController.searchResultsTableView 
        NSLog("Trying recieve indexPath from Search")
        indexPath = self.searchDisplayController.searchResultsTableView.indexPathForSelectedRow()
        NSLog("indexPath from Search")
    
    else 
        indexPath = self.tableView.indexPathForSelectedRow()
        NSLog("IndexPath from main table")
    

    let destViewController:DetailViewController! = segue.destinationViewController as DetailViewController

    if segue.identifier == "editPerson" 
        destViewController.receivedPerson = results
        destViewController.indexPath = indexPath
        NSLog("Selected person ID: \(results[indexPath.row].idperson)")
    


override func tableView(tableView: UITableView?, canEditRowAtIndexPath indexPath: NSIndexPath?) -> Bool 
    return true



override func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) 

    let request = NSFetchRequest(entityName: "Person")
    request.returnsObjectsAsFaults = false
    let appDelegate:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
    let context:NSManagedObjectContext = appDelegate.managedObjectContext

    if editingStyle == .Delete 
        context.deleteObject(results[indexPath.row])
        context.save(nil)
    

    results.removeAtIndex(indexPath.row)
    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)



func filterContentForSearchText (searchText: String) 
    searchResults = results.filter
        ($0.lastname as NSString).localizedCaseInsensitiveContainsString("\(searchText)")
    


func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchString searchString: String!) -> Bool 
    self.filterContentForSearchText (searchString)
    return true

在函数prepareForSegue 条件self.tableView == self.searchDisplayController.searchResultsTableView 不满足。

总是分配indexPath = self.tableView.indexPathForSelectedRow() 而不是indexPath = self.searchDisplayController.searchResultsTableView.indexPathForSelectedRow()。这会导致在搜索结果中选择一行时出错。

Dropbox 上的项目链接:https://www.dropbox.com/s/bqv46nkoa4s3ibg/lesson-12-2-swift%203.zip

【问题讨论】:

【参考方案1】:

self.tableView是主表视图,所以条件

if self.tableView == self.searchDisplayController.searchResultsTableView

永远不会是真的。但是您可以检查搜索是否处于活动状态:

if self.searchDisplayController.active 
    // index path from search table ... 
 else 
    // index path from main table ...

【讨论】:

以上是关于searchDisplayController、UITableView、Core Data 和 Swift的主要内容,如果未能解决你的问题,请参考以下文章

容器覆盖 UITableView - iOS 7 中的 SearchBar / SearchDisplayController

在带有搜索按钮的导航栏上添加 searchDisplayController.displaySearchBarInNavigationBar

使用 UIRefreshControl

显示 searchResultsTableView 时隐藏 UITableView

UISearchDisplayController 的正确实例化

在表格视图中实现搜索栏 [重复]