tableView
의 셀 내용을 소싱하여 CoreData
에서 SearchDisplayController
(대체)을 새로운 SearchController
으로 바 꾸었습니다. 동일한 tableView
컨트롤러를 사용하여 개체의 전체 목록과 필터링 된/검색 한 개체를 모두 표시합니다.UISearchController의 필터링 된 검색 결과에서 삭제
필자는 검색/필터링 작업이 정상적으로 처리되었으며 필터링 된 목록에서 해당 항목에 대한 상세보기로 이동 한 다음 변경 사항을 편집하고 필터링 된 tableView에 성공적으로 다시 저장할 수 있습니다. 필터링 된 목록에서 셀을 삭제하도록 내 문제가 발생하면 런타임 오류가 발생합니다. 불행하게도 그러한있는 tableView가에서 UISearchController
및 임 노출되지
func controllerDidChangeContent(controller: NSFetchedResultsController) {
// If the search is active do this
searchDisplayController!.searchResultsTableView.endUpdates()
// else it isn't active so do this
tableView.endUpdates()
}
}
을 : 나는 그래서 다음 (의사) 코드가 잘 작동 할 것 SearchDisplayController's
결과를 tableView에 대한 액세스 권한을 가지고로 이전에 SearchDisplayController
와 나는 쉽게 할 수 손실. 나는 tableView.beginUpdates()
과 tableView.endUpdates()
을 tableView에 대한 조건부 검색을 tableView가 아니지만 성공으로 만들려고했습니다. 기록을 위해
이 내 오류 메시지입니다 :
이Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.65/UITableView.m:1582
* EDIT *
내있는 tableView는 CoreData에서 자신을 채울 FetchedResultsController를 사용합니다. 이 tableViewController는 SearchController가 필터링 된 결과를 표시하는 데 사용되는 컨트롤러이기도합니다.
var searchController: UISearchController!
다음의 viewDidLoad
searchController = UISearchController(searchResultsController: nil)
searchController.dimsBackgroundDuringPresentation = false
searchController.searchResultsUpdater = self
searchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = searchController?.searchBar
self.tableView.delegate = self
self.definesPresentationContext = true
및
에func updateSearchResultsForSearchController(searchController: UISearchController) {
let searchText = self.searchController?.searchBar.text
if let searchText = searchText {
searchPredicate = searchText.isEmpty ? nil : NSPredicate(format: "locationName contains[c] %@", searchText)
self.tableView.reloadData()
}
}
지금까지 오류 메시지에 관한 한, 내가 추가 할 수 있습니다 얼마나 확실하지 않다. 앱은 스 와이프하여 표시되는 빨간색 삭제 버튼 (계속 표시됨)을 누르면 즉시 멈 춥니 다. 이것은 1 - 5에 대한 스레드 오류 로그입니다. 응용 프로그램이 번호 4에 걸려있는 것 같습니다.
#0 0x00000001042fab8a in objc_exception_throw()
#1 0x000000010204b9da in +[NSException raise:format:arguments:]()
#2 0x00000001027b14cf in -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]()
#3 0x000000010311169a in -[UITableView _endCellAnimationsWithContext:]()
#4 0x00000001019b16f3 in iLocations.LocationViewController.controllerDidChangeContent (iLocations.LocationViewController)(ObjectiveC.NSFetchedResultsController) ->() at /Users/neilmckay/Dropbox/Programming/My Projects/iLocations/iLocations/LocationViewController.swift:303
#5 0x00000001019b178a in @objc iLocations.LocationViewController.controllerDidChangeContent (iLocations.LocationViewController)(ObjectiveC.NSFetchedResultsController) ->()()
나는 이것이 도움이되기를 바랍니다.
EDIT * 2 *
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
let location: Location = self.fetchedResultsController.objectAtIndexPath(indexPath) as Location
location.removePhotoFile()
let context = self.fetchedResultsController.managedObjectContext
context.deleteObject(location)
var error: NSError? = nil
if !context.save(&error) {
abort()
}
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.searchPredicate == nil {
let sectionInfo = self.fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo
return sectionInfo.numberOfObjects
} else {
let filteredObjects = self.fetchedResultsController.fetchedObjects?.filter() {
return self.searchPredicate!.evaluateWithObject($0)
}
return filteredObjects == nil ? 0 : filteredObjects!.count
}
}
// MARK: - NSFetchedResultsController methods
var fetchedResultsController: NSFetchedResultsController {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest = NSFetchRequest()
// Edit the entity name as appropriate.
let entity = NSEntityDescription.entityForName("Location", inManagedObjectContext: self.managedObjectContext!)
fetchRequest.entity = entity
// Set the batch size to a suitable number.
fetchRequest.fetchBatchSize = 20
// Edit the sort key as appropriate.
if sectionNameKeyPathString1 != nil {
let sortDescriptor1 = NSSortDescriptor(key: sectionNameKeyPathString1!, ascending: true)
let sortDescriptor2 = NSSortDescriptor(key: sectionNameKeyPathString2!, ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor1, sortDescriptor2]
} else {
let sortDescriptor = NSSortDescriptor(key: "firstLetter", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
}
var sectionNameKeyPath: String
if sectionNameKeyPathString1 == nil {
sectionNameKeyPath = "firstLetter"
} else {
sectionNameKeyPath = sectionNameKeyPathString1!
}
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: sectionNameKeyPath, cacheName: nil /*"Locations"*/)
aFetchedResultsController.delegate = self
_fetchedResultsController = aFetchedResultsController
var error: NSError? = nil
if !_fetchedResultsController!.performFetch(&error) {
fatalCoreDataError(error)
}
return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController? = nil
func controllerWillChangeContent(controller: NSFetchedResultsController) {
if searchPredicate == nil {
tableView.beginUpdates()
} else {
(searchController.searchResultsUpdater as LocationViewController).tableView.beginUpdates()
}
// tableView.beginUpdates()}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
var tableView = UITableView()
if searchPredicate == nil {
tableView = self.tableView
} else {
tableView = (searchController.searchResultsUpdater as LocationViewController).tableView
}
switch type {
case .Insert:
tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
case .Delete:
tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
default:
return
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath) {
var tableView = UITableView()
if searchPredicate == nil {
tableView = self.tableView
} else {
tableView = (searchController.searchResultsUpdater as LocationViewController).tableView
}
switch type {
case .Insert:
println("*** NSFetchedResultsChangeInsert (object)")
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
case .Delete:
println("*** NSFetchedResultsChangeDelete (object)")
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
case .Update:
println("*** NSFetchedResultsChangeUpdate (object)")
if searchPredicate == nil {
let cell = tableView.cellForRowAtIndexPath(indexPath) as LocationCell
let location = controller.objectAtIndexPath(indexPath) as Location
cell.configureForLocation(location)
} else {
let cell = tableView.cellForRowAtIndexPath(searchIndexPath) as LocationCell
let location = controller.objectAtIndexPath(searchIndexPath) as Location
cell.configureForLocation(location)
}
case .Move:
println("*** NSFetchedResultsChangeMove (object)")
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
if searchPredicate == nil {
tableView.endUpdates()
} else {
(searchController.searchResultsUpdater as LocationViewController).tableView.endUpdates()
}
}
SearchController 구성, 'updateSearchResultsForSearchController' 메소드 및 오류 메시지에 대한 자세한 정보에 대해 자세히 알려주십시오. 감사. – pbasdf
원본 답변에 몇 가지 정보를 추가했습니다. 희망이 도움이됩니다. – Magnas
감사합니다. tableView.endUpdates()가 호출 될 때 오류가 발생하더라도 문제는 다른 곳에 있다고 생각합니다. 나는 그 문제가 삭제 후'numberOfRowsInSection'에 의해 반환 된 숫자가 이전 값과 일치하지 않는다고 의심한다. 만약 당신이 한 행을 삭제했다면, 이전 값 -1이어야한다. 질문) 코드에서'commitEditingStyle'와'numberOfRowsInSection'과 다른 FRC 델리게이트 메소드 – pbasdf