无法在 UITableViewCell 内的 UILabel 中显示来自核心数据的 Double
Posted
技术标签:
【中文标题】无法在 UITableViewCell 内的 UILabel 中显示来自核心数据的 Double【英文标题】:Can't show Double from CoreData in UILabel inside a TableViewCell 【发布时间】:2015-08-10 13:02:13 【问题描述】:在这个表格视图 (override func tableView
) 中,我显示了兴趣点,一些是默认加载的,另一些是由用户加载的。我可以检索托管对象的名称,但是当尝试显示位置时,它失败了。
我无法在TableViewCell
中显示纬度和经度。如果我使用 name
关键字,则会出现名称。也许我应该对数字进行某种转换,但是在哪里?
我也收到了这个警告:
CoreData:警告:无法为实体“ArcheoPOI”加载名为“PRODUCT_MODULE_NAME.ArcheoPOI”的类。找不到类,改用默认的 NSManagedObject。
这是我的NSManagedContext
import UIKit
import CoreData
import CoreLocation
class AppiaTVC: UITableViewController, UITableViewDataSource, UITableViewDelegate
var places : [NSManagedObject] = []
let myLocationManager = CLLocationManager()
override func viewDidLoad()
super.viewDidLoad()
//MARK : good way to set the reuse id of the cell
// tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell") //alternative to put it in the
//MARK : good way to set the table title
title = "\"All the POI\""
//MARK: - Added for fetching data from CoreData
override func viewWillAppear(animated: Bool)
super.viewWillAppear(animated)
//1
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext! //needed to handel mangedObject (saving and fetching entries)
//2
let fetchRequest = NSFetchRequest(entityName:"ArcheoPOI")
//3
var error: NSError?
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as? [NSManagedObject]
if let results = fetchedResults
places = results
else
println("Could not fetch \(error), \(error!.userInfo)")
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return places.count
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("appiaCellID", forIndexPath: indexPath) as! AppiaTVCell
cell.backgroundColor = UIColor.blueColor()
if indexPath.row % 2 == 0
// cell.backgroundColor = UIColor(red: 143 / 255, green: 204 / 255, blue: 255 / 255, alpha: 1)
// cell.sweetTextView.backgroundColor = UIColor(red: 63 / 255, green: 159 / 255, blue: 255 / 255, alpha: 1)
else
// cell.backgroundColor = UIColor(red: 63 / 255, green: 159 / 255, blue: 255 / 255, alpha: 1)
// cell.sweetTextView.backgroundColor = UIColor(red: 143 / 255, green: 204 / 255, blue: 255 / 255, alpha: 1)
let singlePlace = places[indexPath.row]
//KVC is the only way to access data in CoreData (can't use a property) butwe could also use a more natural object-style person.name
// cell.textLabel!.text = singlePlace.valueForKey("name") as? String
cell.cellNameLabel.text = singlePlace.valueForKey("name") as? String
cell.cellLatitudeLabel.text = singlePlace.valueForKey("latitude") as? String //if I use "name" it works
cell.cellLongitudeLabel.text = singlePlace.valueForKey("longitude") as? String //if I use "name" it works
return cell
@IBAction func addPlaceButtonPressed(sender: UIBarButtonItem)
var alert = UIAlertController(title: "New place", message: "Add a new place", preferredStyle: .Alert)
let saveAction = UIAlertAction(title: "Save", style: .Default) (action: UIAlertAction!) -> Void in
let textField = alert.textFields![0] as! UITextField
self.saveName(textField.text) //self.names.append(textField.text)
self.tableView.reloadData()
let cancelAction = UIAlertAction(title: "Cancel", style: .Default) (action: UIAlertAction!) -> Void in
alert.addTextFieldWithConfigurationHandler
(textField: UITextField!) -> Void in
alert.addAction(saveAction)
alert.addAction(cancelAction)
presentViewController(alert,
animated: true,
completion: nil)
//MARK: - save data to CoreData - this function is called by the addName button
func saveName(name: String)
//1
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let entity = NSEntityDescription.entityForName("ArcheoPOI", inManagedObjectContext: managedContext) //NSEntityDescription is required
let place = NSManagedObject(entity: entity!, insertIntoManagedObjectContext:managedContext)
myLocationManager.startUpdatingLocation()
let lat = myLocationManager.location.coordinate.latitude
let lon = myLocationManager.location.coordinate.longitude
myLocationManager.stopUpdatingLocation()
println("************************")
println(lat)
println(lon)
println("************************")
//3
place.setValue(name, forKey: "name")
place.setValue(lat, forKey: "latitude")
place.setValue(lon, forKey: "longitude")
//4
var error: NSError?
if !managedContext.save(&error)
println("Could not save \(error), \(error?.userInfo)")
//5
places.append(place)
//MARK - delete NSManagedObject
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
switch editingStyle
case UITableViewCellEditingStyle.Delete:
// remove the deleted item from the model
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext:NSManagedObjectContext = appDelegate.managedObjectContext!
managedContext.deleteObject(places[indexPath.row] as NSManagedObject)
places.removeAtIndex(indexPath.row)
managedContext.save(nil)
//tableView.reloadData()
// remove the deleted item from the `UITableView`
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
default:
return
@IBAction func BackButtonPressed(sender: UIBarButtonItem)
dismissViewControllerAnimated(true , completion: nil)
【问题讨论】:
【参考方案1】:将代码更改为
let latitude = singlePlace.valueForKey("latitude")
let longitude = singlePlace.valueForKey("longitude")
cell.cellLatitudeLabel.text = "\(latitude)" //if I use "name" it works
cell.cellLongitudeLabel.text = "\(longitude)" //if I use "name" it works
我也强烈建议你创建一个类来管理你的实体。您可以在here 找到有关如何操作的良好说明。本教程是在 Objective-c 中,但从那以后没有什么太大的变化;)
然后您就可以拨打singlePlace.latitutde
而不是使用valueForKey
,
【讨论】:
您的代码有问题:字符串插值中出现意外的 '"' 字符 感谢您的帮助和提示,但我必须添加“as!NSNumber”。有没有合适的方法来查看和编辑我的 coreData 中的内容?我想通过 Xcode 从列表中添加许多对象 按照我参考的教程进行操作。它向您展示了如何轻松地为您的实体创建子类,这将允许您在不使用 if valueForKey 的情况下访问实体的属性【参考方案2】:这是针对您提到的 CoreData 警告:
查看 .xcdatamodeld 文件中的实体时,打开Utilities
选项卡并查看Data Model inspector
部分。 Module
有一个下拉列表。对于一些较新的 Xcode 7 测试版,默认情况下会显示 Current Product Module
。删除它并将其留空。这应该可以解决您的问题。
【讨论】:
我看到的唯一下拉菜单是“父实体” 您使用的是哪个 Xcode 版本?这是我自 Xcode 7b3 或 7b4 以来才看到的警告。如果您使用较早的 Xcode,则该下拉菜单可能不存在,并且警告可能来自其他内容。 不是测试版,Xcode 6.4 也许我不应该使用 struct 并使用 100% coreData,如上面的答案中所建议的......以上是关于无法在 UITableViewCell 内的 UILabel 中显示来自核心数据的 Double的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewCell 内的 UIStackView 在 AutoLayout 上无法正确调整
无法在 UITableViewCell 内的 UILabel 中显示来自核心数据的 Double
无法更改 UITableViewCell 内的 UIButton 图像