ios - 将 UITableViewController 更改为 UITableView 会使应用程序崩溃

标签 ios swift uitableview

我刚刚从 UITableViewController 更改为 UITableView,一切正常,除了搜索栏,当点击键盘将使应用程序崩溃并出现错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier rideCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

我没有对代码进行任何更改。有人建议更改:

let cell = tableView.dequeueReusableCellWithIdentifier("rideCell", forIndexPath: indexPath) as! RideCell

到:

let cell = tableView.dequeueReusableCellWithIdentifier("rideCell") as! RideCell

但这根本没有帮助。

有什么建议吗?

编辑:

这是我要求的代码:

初始化 View Controller 类:UIViewController、UITableViewDelegate、UITableViewDataSource {

@IBOutlet var tableView: UITableView!
@IBOutlet weak var searchBar: UISearchBar!

var rideName = ""

var parkPassed: Park!

var searchResults = NSArray()

var loadingIndicator = UIActivityIndicatorView()
var backgroundLabel = LabelWithInsets()

var refreshSpinner = UIRefreshControl()

func handleRefresh(refreshControl: UIRefreshControl) {
    DataManager.sharedInstance.loadRides(parkPassed.name!.stringByReplacingOccurrencesOfString(" ", withString: ""))

    refreshControl.endRefreshing()
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    backgroundLabel.textAlignment = NSTextAlignment.Center
    backgroundLabel.textColor = UIColorFromRGB(0x424242)
    backgroundLabel.numberOfLines = 0

    refreshSpinner.addTarget(self, action: "handleRefresh:", forControlEvents: UIControlEvents.ValueChanged)
    tableView.addSubview(refreshSpinner)
    //refreshControl = refreshSpinner

    self.tableView.tableHeaderView = searchBar
    self.tableView.contentOffset = CGPointMake(0, CGRectGetHeight(searchBar.frame))

    self.navigationController?.navigationBar.barTintColor = UIColorFromRGB(0x0096FF)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateTableView", name: "onRidesLoadedNotification", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "displayError", name: "onRidesLoadFailedNotification", object: nil)        
}

override func viewWillAppear(animated: Bool) {
    if DataManager.sharedInstance.rideArray.count == 0 {
        tableView.separatorStyle = UITableViewCellSeparatorStyle.None

        loadingIndicator.frame = CGRectMake((view.bounds.width / 2) - 25, (view.bounds.height / 2) - 50, 50, 50)
        loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
        view.addSubview(loadingIndicator)
        loadingIndicator.startAnimating()

        backgroundLabel.text = "Loading rides..."
        backgroundLabel.frame = CGRectMake(0, (view.bounds.height / 2) - 80, view.bounds.width, 30)
        view.addSubview(backgroundLabel)
    }

    DataManager.sharedInstance.loadRides(parkPassed.name!.stringByReplacingOccurrencesOfString(" ", withString: ""))

    UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: false)

    if NSUserDefaults.standardUserDefaults().arrayForKey("favourites") != nil {
        let tempFavourites: NSArray = NSUserDefaults.standardUserDefaults().arrayForKey("favourites")!
        favouritesArray = tempFavourites.mutableCopy() as! NSMutableArray
    }
}

@IBAction func dismiss(sender: AnyObject) {
    self.dismissViewControllerAnimated(true, completion: nil)
}

func updateTableView() {
    tableView.reloadData()

    tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
    loadingIndicator.removeFromSuperview()
    backgroundLabel.removeFromSuperview()
}

func displayError() {
    loadingIndicator.removeFromSuperview()
    backgroundLabel.removeFromSuperview()

    backgroundLabel.text = "Failed to load rides. Please check your internet connection."
    backgroundLabel.frame = CGRectMake(0, (view.bounds.height / 2) - 80, view.bounds.width, 60)
    view.addSubview(backgroundLabel)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func viewDidAppear(animated: Bool) {
    println(DataManager.sharedInstance.rideArray.count)
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("rideCell", forIndexPath: indexPath) as! RideCell

    var ride: Ride

    if tableView == self.searchDisplayController?.searchResultsTableView {
        ride = DataManager.sharedInstance.getRideByName(searchResults[indexPath.row].name)!
    } else {
        ride = DataManager.sharedInstance.rideAtLocation(indexPath.row)!
    }

    cell.rideNameLabel.text = ride.name

    var dateSinceUpdate = NSDate().timeIntervalSinceDate(ride.updated!)
    var secondsSinceUpdate = Int(dateSinceUpdate)
    var timeSinceUpdate = printSecondsConvert(secondsSinceUpdate)

    cell.updatedLabel.text = timeSinceUpdate

    if ride.waitTime == "Closed" {
        cell.waitTimeLabel.text = ride.waitTime!
        cell.timeBackgroundView.backgroundColor = getColorFromNumber(80)
        cell.waitTimeLabel.font = UIFont(name: "Avenir", size: 13)
    } else {
        cell.waitTimeLabel.text = "\(ride.waitTime!)m"
        cell.timeBackgroundView.backgroundColor = getColorFromNumber(ride.waitTime!.toInt()!)
        cell.waitTimeLabel.font = UIFont(name: "Avenir", size: 17)
    }

    AsyncImageLoader.sharedLoader().cancelLoadingURL(cell.rideImageView.imageURL)
    cell.rideImageView.image = UIImage(named: "Unloaded")
    cell.rideImageView.imageURL = NSURL(string: ride.rideImageSmall!)

    return cell
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if tableView == self.searchDisplayController?.searchResultsTableView {
        return searchResults.count
    } else {
        return DataManager.sharedInstance.rideArray.count
    }
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let currentCell = tableView.cellForRowAtIndexPath(indexPath) as! RideCell!

    rideName = currentCell.rideNameLabel.text!

    performSegueWithIdentifier("showDetail", sender: self)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "showDetail") {
        var viewController = segue.destinationViewController as! DetailViewController

        viewController.currentRide = DataManager.sharedInstance.getRideByName(rideName)
        viewController.parkPassed = parkPassed
    }
}

func filterContentForSearchText(searchText: NSString) {
    let resultPredicate = NSPredicate(format: "name contains[cd] %@", searchText) //Use either contains or beginswith
    searchResults = (DataManager.sharedInstance.rideArray as NSArray).filteredArrayUsingPredicate(resultPredicate)
}

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

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 71
}

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
    var cell = tableView.cellForRowAtIndexPath(indexPath) as! RideCell

    let favourite = UITableViewRowAction(style: .Normal, title: "          ") { action, index in
        if favouritesArray.containsObject(cell.rideNameLabel.text!) {
            favouritesArray.removeObject(cell.rideNameLabel.text!)
        } else {
            favouritesArray.addObject(cell.rideNameLabel.text!)
        }
        NSUserDefaults.standardUserDefaults().setObject(favouritesArray, forKey: "favourites")
        tableView.setEditing(false, animated: true)
    }

    if favouritesArray.containsObject(cell.rideNameLabel.text!) {
        favourite.backgroundColor = UIColor(patternImage: UIImage(named: "Unfavourite")!)
    } else {
        favourite.backgroundColor = UIColor(patternImage: UIImage(named: "Favourite")!)
    }

    return [favourite]
}

func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
}

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
}

最佳答案

在包含您的 TableView 的 View Controller 的 viewDidLoad 方法中调用下一个代码:
如果您在 xib 中创建了 RideCell:

tableView.registerNib(UINib(nibName: "RideCell", bundle: nil),
     forCellReuseIdentifier: "rideCell")  

如果您在代码中创建了 RideCell:

tableView.registerClass(RideCell.self, forCellReuseIdentifier: "rideCell")

关于ios - 将 UITableViewController 更改为 UITableView 会使应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31663287/

相关文章:

ios - CoreData 返回与 >0 个实体有关系的实体以及这些关系的数量

ios - 为什么前导/尾随空格显示为 -16?

ios - 如何确保我的详细信息 View Controller 始终嵌入到 UINavigationController 中?

ios - Spika-iOS : "incompatible block pointer types"

ios - 为什么 SecPKCS12Import 会自动将 SecIdentities 添加到钥匙串(keychain)中?

swift 3 |核心数据 |自定义实体

ios - 当使用 Batch 为 iOS 开发的 Swift 中的用户更改 Firebase 数据库节点值时如何触发远程推送通知?

ios - 如何使用 willDisplayCell 方法实现多个自定义单元格?

objective-c - viewDidLoad 在 didSelectRowAtIndexPath 之前被调用

swift - 水平 UITableView - Swift