如何在swift3中以其他方法更新UITableviewcell标签?
Posted
技术标签:
【中文标题】如何在swift3中以其他方法更新UITableviewcell标签?【英文标题】:How to update UITableviewcell label in other method in swift3? 【发布时间】:2017-09-29 07:40:42 【问题描述】:我正在尝试用其他方法更新 UITableviewcell 的标签。我还看到了很多关于 *** 的帖子,对我来说不是工作。我正在使用 Swift 3,我尝试了这个:
let indexPath = IndexPath.init(row: 0, section: 0)
let cell : CategoryRow = tableView.cellForRow(at: indexPath) as! CategoryRow
我收到了这个错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
我在其他方法中使用它,我在 24 小时后更新 tableviewcell 标签文本。 代码在这里
var myQuoteArray = ["“If you have time to breathe you have time to meditate. You breathe when you walk. You breathe when you stand. You breathe when you lie down. – Ajahn Amaro”","We are what we repeatedly do. Excellence, therefore, is not an act but a habit. – Aristotle","The best way out is always through. – Robert Frost","“If you have time to breathe you have time to meditate. You breathe when you walk. You breathe when you stand. You breathe when you lie down. – Ajahn Amaro”","We are what we repeatedly do. Excellence, therefore, is not an act but a habit. – Aristotle","The best way out is always through. – Robert Frost"
]
func checkLastRetrieval()
// let indexPath = IndexPath.init(row: 0, section: 0)
// let cell : CategoryRow = tableView.cellForRow(at: indexPath) as? CategoryRow
let indexPath = IndexPath.init(row: 0, section: 0)
guard let cell = tableView.cellForRow(at: indexPath) as? CategoryRow else return
print("Getting Error line 320")// This is not printing on console
let userDefaults = UserDefaults.standard
if let lastRetrieval = userDefaults.dictionary(forKey: "lastRetrieval")
if let lastDate = lastRetrieval["date"] as? NSDate
if let index = lastRetrieval["index"] as? Int
if abs(lastDate.timeIntervalSinceNow) > 86400 // seconds in 24 hours
// Time to change the label
var nextIndex = index + 1
// Check to see if next incremented index is out of bounds
if self.myQuoteArray.count <= nextIndex
// Move index back to zero? Behavior up to you...
nextIndex = 0
cell?.quotationLabel.text = self.myQuoteArray[nextIndex]
let lastRetrieval : [NSObject : AnyObject] = [
"date" as NSObject : NSDate(),
"index" as NSObject : nextIndex as AnyObject
]
userDefaults.set(lastRetrieval, forKey: "lastRetrieval")
userDefaults.synchronize()
// Do nothing, not enough time has elapsed to change labels
else
// No dictionary found, show first quote
cell?.quotationLabel.text = self.myQuoteArray.first!
print("line 357")
// Make new dictionary and save to NSUserDefaults
let lastRetrieval : [NSObject : AnyObject] = [
"date" as NSObject : NSDate(),
"index" as NSObject : 0 as AnyObject
]
userDefaults.set(lastRetrieval, forKey: "lastRetrieval")
userDefaults.synchronize()
并在 ViewDidLoad() 中调用此方法
override func viewDidLoad()
super.viewDidLoad()
checkLastRetrieval()
我该怎么办? 提前致谢
【问题讨论】:
使用 ? 使 CategoryRow 标签可选而不是! 我认为您正在更新单元格,而表格视图中没有单元格。 当您尝试这样做时,此单元格是否可见? Nauman Malik,我已经做到了。但是没有用。 您的表格视图不会在viewDidLoad
中呈现,因此此时屏幕上不会有任何单元格。直到viewDidAppear
,单元格才会出现在屏幕上。正如我在下面的评论中所说,正确的做法是更新表格的数据模型,以便在随后加载单元格时显示正确的数据。
【参考方案1】:
如果请求的单元格当前不在屏幕上,则函数cellForRow(at:)
返回nil
。由于您在viewDidLoad
中调用您的函数,因此屏幕上将没有单元格。这会导致崩溃,因为您强制向下转换 cellForRow(at:)
的结果。
你不应该使用强制展开或强制向下转换,除非你绝对
确定结果不能是nil
和/或如果是nil
,唯一可能的操作是让您的应用崩溃。
通常您不应直接更新单元格。最好更新表格的数据模型,然后调用reloadRows(at:,with:)
并让您的数据源cellForRow(at:)
函数处理更新单元格。
如果您要直接更新单元格,请确保使用带有if let
或guard let
的条件向下转换,以避免在单元格不可见时发生崩溃。在这种情况下,您仍然需要更新数据模型,以便当单元格出现在屏幕上时单元格数据是正确的。
【讨论】:
感谢 Paulw11,现在我可以正确获取单元格,但我的标签文本仍未更新。 您试图在viewDidLoad
中运行代码的事实让我感到怀疑;如果单元格已经在屏幕上,为什么需要在viewDidLoad
中运行任何东西?我怀疑您正在创建视图控制器的新实例并更新它,而不是更新屏幕上已经存在的实例。您的更新似乎是基于时间的。计时器在哪里运行?当它着火时你会怎么做?
根据 Apple 描述,我不能玩超过 3 分钟的计时器,这就是为什么我将自定义数据存储在字典中,而不是从上次日期检查它而不是更新标签。可能是我做错了吗?
我无法理解的是你为什么要做这一切;您需要做的就是在应用程序加载时将数据加载到表中,并检查当您的应用程序返回前台时是否需要刷新数据。如果是,请重新加载该行。【参考方案2】:
你应该使用guard let
声明:
let indexPath = IndexPath(row: 0, section: 0)
guard let cell = tableView.cellForRow(at: indexPath) as? CategoryRow else return
如果您的cell
类型不是CategoryRow
,您将从该方法返回。尝试找出为什么您的cell
类型不是CategoryRow
。
【讨论】:
感谢您的回复,我有一个 CategoryRow 单元格,它工作正常,其他元素在 cellForRowAtIndexPath 中正确显示。但它在外面不起作用。 更重要的是,如果单元格当前不在屏幕上,cellForRow(at:)
将返回 nil
;您应该按照建议使用if let
或guard let
对此做好准备。通常,您应该更新数据源,然后重新加载受影响的行,而不是直接更新单元格。
@ChetanLodhi,您在哪里使用此代码(哪种方法)?
V.Khambir ......实际上我在其他方法中使用此代码,我在 24 小时后更新标签文本。并且这个方法在 Viewdidload 中被调用。
@ChetanLodhi,可能,此时您在 IndexPath(row: 0, section: 0) 处没有任何单元格。以上是关于如何在swift3中以其他方法更新UITableviewcell标签?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift3 iOS 中以特定时间在 AVPlayer 中播放视频
在 Swift 中以编程方式访问和更新 stackview 中的 label.text 或其他 UILabel 属性
如何在 Android Studio 中以除 onCreate 之外的其他方法获取应用程序的上下文?