新表格视图单元格显示为空白单元格

新表格视图单元格显示为空白单元格

本文介绍了新表格视图单元格显示为空白单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在开发一个应用程序,但遇到了一些问题,所以我尽可能简单地重新构建它以找出错误发生的位置.我的代码使用 CoreData,我的第一个示例包含在导航栏中的加号按钮内添加新项目的代码.换句话说,没有改变观点或转场.这个版本按我的预期工作.请参阅以下 GIF.

I've been working on an app, and ran into some problems, so I rebuilt it as simple as possible to find where the error happens at. My code uses CoreData, and my first example has the code for adding new items inside the plus button in the navigation bar. In other words, there is no change of view or segue. This version works as I would expect it to. See the following GIF.

但是当我创建一个添加新项目的新视图控制器时,我最终得到了一个空白单元格.我在加号按钮中的添加按钮后面有完全相同的代码.我只是使用 show segue 从 tableview 到普通的视图控制器.但是如果我退出应用程序并重新启动它,它都会正确显示.见下文.

But when I make a new view controller that adds the new item, I end up getting a blank cell instead. I have the exact same code behind the add button that I had in the plus button. And I just use a show segue to get from the tableview to a normal view controller. But if I quit the app and start it back up, it all shows correctly. See below.

如果你很好奇,我有一个部分,它被添加为 1 到 3 之间的随机数.我猜我需要对那个 segue 做一些事情,但我不知道它是什么.我是 Swift 的新手,所以我有很多东西要学习.

If you are curious, I have the section it is adding to being a random number between 1 and 3. My guess is there is something I need to do with that segue but I don't have clue what it is. I'm very new at Swift so I have lots to learn.

预先感谢您为我提供的任何帮助.我想如果我能解决这个问题,我终于可以继续开发我的应用程序了.再次感谢你.下面是我的代码,用于它有 segue 的情况.

Thank you in advance for any help you can give me. I think if I can solve this problem, I can finally move forward with developing my app. Thank you again. Below is my code for the case where it has a segue.

表视图控制器代码 (Swift)

Table View Controller Code (Swift)

import UIKit
import CoreData

class ListItemsTVC: UITableViewController, NSFetchedResultsControllerDelegate {

// MARK: - Constants and Variables

let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var frc: NSFetchedResultsController = NSFetchedResultsController()

// MARK: - App loading Functions

override func viewDidLoad() {
    super.viewDidLoad()

    frc = getFCR()
    frc.delegate = self

    do {
        try frc.performFetch()
    } catch {
        print("Failed to perform inital fetch")
    }
    self.tableView.rowHeight = 62

}

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

// MARK: - Outlets and Actions

/*@IBAction func addItem(sender: AnyObject) {

    let entityDesc = NSEntityDescription.entityForName("Items", inManagedObjectContext: moc)
    let item = Items(entity: entityDesc!, insertIntoManagedObjectContext: moc)

    if (NSUserDefaults.standardUserDefaults().objectForKey("nextItemID") == nil) {
        NSUserDefaults.standardUserDefaults().setObject(1, forKey: "nextItemID")
        NSUserDefaults.standardUserDefaults().synchronize()
    }

    let id = NSUserDefaults.standardUserDefaults().integerForKey("nextItemID")

    item.id = id
    switch id {
    case 1...9:
        item.name = "Item ID: 0\(id)"
    default:
        item.name = "Item ID: \(id)"
    }
    item.brand = "Brand \(id)"
    item.qty = 1
    item.price = 0
    item.size = "Size \(id)"
    let sec: Int = Int(arc4random_uniform(UInt32(4 - 1))) + 1
    item.section = "Section \(sec)"
    item.isChecked = false

    do {
        try moc.save()
        NSUserDefaults.standardUserDefaults().setObject(id + 1, forKey: "nextItemID")
        NSUserDefaults.standardUserDefaults().synchronize()
    } catch {
        fatalError("New item save failed")
    }

}*/

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {

    if let sections = frc.sections {
        return sections.count
    }

    return 0

}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if let sections = frc.sections {
        let currentSection = sections[section]
        return currentSection.numberOfObjects
    }

    return 0

}

override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

    return 28

}

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

    if let sections = frc.sections {
        let currentSection = sections[section]
        return currentSection.name
    }

    return nil

}

func controllerWillChangeContent(controller: NSFetchedResultsController) {

    tableView.beginUpdates()

}

func controllerDidChangeContent(controller: NSFetchedResultsController) {

    tableView.endUpdates()

}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("listContentCell", forIndexPath: indexPath) as! ListItemsTVCell
    let item = frc.objectAtIndexPath(indexPath) as! Items

    cell.separatorInset = UIEdgeInsets(top: 0, left: 78, bottom: 0, right: 0)
    cell.itemName.text = item.name
    cell.itemSection.text = item.section
    cell.itemQty.text = "Qty: \(item.qty!)"
    cell.itemSize.text = item.size
    cell.itemPrice.text = floatToCurrency(Float(item.price!))
    //cell.itemImage.image = UIImage(data: item.image!)
    cell.itemID.text = String(item.id!)

    return cell

}

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {

    let delete = UITableViewRowAction(style: .Destructive, title: "Delete") { (action, indexPath) in

        let item = self.frc.objectAtIndexPath(indexPath) as! Items
        let id = item.id!
        let request = self.fetchRequest()
        let pred = NSPredicate(format: "%K == %@", "id",id)
        request.predicate = pred
        var fetchResults = [AnyObject]()

        do {
            fetchResults = try self.moc.executeFetchRequest(request)
        } catch {
            fatalError("Fetching Data to Delete Failed")
        }

        self.moc.deleteObject(fetchResults[0] as! NSManagedObject)
        fetchResults.removeAtIndex(0)

        do {
            try self.moc.save()
        } catch {
            fatalError("Failed to Save after Delete")
        }

    }

    return [delete]

}

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {

    switch type {
    case NSFetchedResultsChangeType.Delete:
        self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
    case NSFetchedResultsChangeType.Insert:
        self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
        /*case NSFetchedResultsChangeType.Update:
         tableView.reloadSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)*/
    default:
        print("Default in didChangeSection was called")
        break
    }

}

internal func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

    switch type {
    case NSFetchedResultsChangeType.Delete:
        self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
    case NSFetchedResultsChangeType.Insert:
        self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.Fade)
    default:
        print("Default in didChangeObject was called")
        break
    }

}

/*
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return false if you do not want the specified item to be editable.
    return true
}
*/

/*
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        // Delete the row from the data source
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    } else if editingStyle == .Insert {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }
}
*/

/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

}
*/

/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return false if you do not want the item to be re-orderable.
    return true
}
*/

/*

// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

// MARK: - Custom Functions

func fetchRequest() -> NSFetchRequest {

    let fetchRequest = NSFetchRequest(entityName: "Items")
    let sortDesc1 = NSSortDescriptor(key: "section", ascending: true)
    let sortDesc2 = NSSortDescriptor(key: "isChecked", ascending: true)
    let sortDesc3 = NSSortDescriptor(key: "name", ascending: true)
    fetchRequest.sortDescriptors = [sortDesc1, sortDesc2, sortDesc3]

    return fetchRequest

}

func getFCR() -> NSFetchedResultsController {

    frc = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: moc, sectionNameKeyPath: "section" , cacheName: nil)

    return frc

}

func floatToCurrency(flt: Float) -> String {

    let formatter = NSNumberFormatter()
    formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
    return String(formatter.stringFromNumber(flt)!)

}

}

视图控制器 (Swift) [转场视图]

View Controller (Swift) [The segue view]

import UIKit
import CoreData

class AddItemListVC: UIViewController, NSFetchedResultsControllerDelegate {

// MARK: - Constants and Variables

let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
//var frc: NSFetchedResultsController = NSFetchedResultsController()

// MARK: - App loading Functions

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
}

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

// MARK: - Outlets and Actions

@IBAction func addItem(sender: AnyObject) {

    let entityDesc = NSEntityDescription.entityForName("Items", inManagedObjectContext: moc)
    let item = Items(entity: entityDesc!, insertIntoManagedObjectContext: moc)

    if (NSUserDefaults.standardUserDefaults().objectForKey("nextItemID") == nil) {
        NSUserDefaults.standardUserDefaults().setObject(1, forKey: "nextItemID")
        NSUserDefaults.standardUserDefaults().synchronize()
    }

    let id = NSUserDefaults.standardUserDefaults().integerForKey("nextItemID")

    item.id = id
    switch id {
    case 1...9:
        item.name = "Item ID: 0\(id)"
    default:
        item.name = "Item ID: \(id)"
    }
    item.brand = "Brand \(id)"
    item.qty = 1
    item.price = 0
    item.size = "Size \(id)"
    let sec: Int = Int(arc4random_uniform(UInt32(4 - 1))) + 1
    item.section = "Section \(sec)"
    item.isChecked = false

    do {
        try moc.save()
        NSUserDefaults.standardUserDefaults().setObject(id + 1, forKey: "nextItemID")
        NSUserDefaults.standardUserDefaults().synchronize()
    } catch {
        fatalError("New item save failed")
    }

}

/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

}

推荐答案

Reload TableView Data is viewWillAppear 方法为:

Reload TableView Data is viewWillAppear method as :

override func viewWillAppear() {
    super.viewWillAppear()
    do {
        try frc.performFetch()
    } catch {
        print("Failed to perform inital fetch")
    }
}

当你从 viewController 导航回来时,你没有告诉 TableViewController 更新 tableView 所以在 viewWillAppear 中这样做,因为当你弹出 navController 时它会触发回来了.

As when you are navigating back from viewController you are not telling the TableViewController to update tableView so do it in viewWillAppear as it will fire when you are popping navController to come back.

这篇关于新表格视图单元格显示为空白单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 10:50