作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目前我的代码是这样的,我在单元格中设置了一个日期选择器
代码 A 有效
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Bundle.main.loadNibNamed("DailyTimesTableViewCell", owner: self, options: nil)?.first as! DailyTimesTableViewCell
cell.endTimeTapped = { (button) -> DailyTimesTableViewCell in
cell.datePicker.date = self.convertToDateObject(timeString: endTime as! String)
}
return cell
}
我想根据一些逻辑修改单元格中的 datePicker,所以当我尝试下面的代码 B 时,使用回调 setTimeInDatePicker
修改单元格中的 datePicker 似乎没有去工作。
请告诉我哪里可能出错。
代码 B:不起作用
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Bundle.main.loadNibNamed("DailyTimesTableViewCell", owner: self, options: nil)?.first as! DailyTimesTableViewCell
cell.endTimeTapped = { (button) -> DailyTimesTableViewCell in
self.setTimeInDatePicker(time: endTime!, cell: cell){ modifiedCell in
return modifiedCell
}
}
return cell
}
func setTimeInDatePicker(time: String, cell: DailyTimesTableViewCell, completionHandler: @escaping(DailyTimesTableViewCell) -> DailyTimesTableViewCell) {
tableView.beginUpdates()
let row = cell.tag
let rows = self.timesArray.count
if self.startTimeHighlighted{
// Setting minimum startTime for datePicker
if row == 0{ // For first row
let minStartTimeString = "0:05 am"
cell.datePicker.minimumDate = self.convertToDateObject(timeString: minStartTimeString)
}
else if row > 0 { // For remaining rows
let endTimeStringOfPreviousCell = self.timesArray[row - 1]["endTime"]!
let endTimeObjectOfPreviousCell = self.convertToDateObject(timeString: endTimeStringOfPreviousCell)
cell.datePicker.minimumDate = endTimeObjectOfPreviousCell
}
// Setting maximum startTime for datepicker
let endTimeString = self.timesArray[row]["endTime"]!
let endTimeObject = self.convertToDateObject(timeString: endTimeString)
let maxStartTimeObject = endTimeObject.addingTimeInterval(-5 * 60.0) // removing 5mins
cell.datePicker.maximumDate = maxStartTimeObject
// Setting selected date in as startTime title
let dateString = self.convertDateToString(cell.datePicker.date)
cell.startTime.setTitle(dateString, for: .normal)
// Saving updated date to the timesArray
self.timesArray[row]["startTime"] = dateString
//print("endTime in DatePickerChanged: \(self.timesArray[row]["endTime"])")
print("timesArray when startTimeHighlighted: \(self.timesArray)")
completionHandler(cell)
}
else if self.endTimeHighlighted{
print("datePicker changed 3")
// Setting minimum endTime for datePicker
let startTimeString = self.timesArray[row]["startTime"]
let startTimeObject = self.convertToDateObject(timeString: startTimeString!)
let minEndTimeObject = startTimeObject.addingTimeInterval(5 * 60.0) // adding 5mins
cell.datePicker.minimumDate = minEndTimeObject
// Setting maximum endTime for datePicker
if rows == 1 || row + 1 == self.timesArray.count{ // For first and last row
let maxEndTimeString = "11:55 pm"
cell.datePicker.maximumDate = self.convertToDateObject(timeString: maxEndTimeString)
}
else{ // If more than one row
let nextCellStartTime = self.timesArray[row + 1]["startTime"]!
let nextCellStartTimeObject = self.convertToDateObject(timeString: nextCellStartTime)
cell.datePicker.maximumDate = nextCellStartTimeObject
}
// Setting selected date in as endTime title
let dateString = self.convertDateToString(cell.datePicker.date)
cell.endTime.setTitle(dateString, for: .normal)
// Saving updated date to the timesArray
self.timesArray[row]["endTime"] = dateString
print("timesArray when endTimeHighlighted: \(self.timesArray)")
completionHandler(cell)
}
tableView.endUpdates()
}
最佳答案
您似乎将 completionHandlers 与其他东西混淆了。
通常在任务异步时使用 completionHandlers。所以简而言之,您开始一项任务(通常是网络),当它完成时(这可能需要很长时间),您有一个处理程序可以调用以让应用程序知道它已完成。
由于应用程序没有等待这个非常长的异步任务完成,它继续运行并且与任务首次启动时的状态不同。简而言之,无论您在完成处理程序中返回什么,都将/不应使用。
基于此,以及一切似乎都是同步的事实,您可以像这样重构您的函数:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Bundle.main.loadNibNamed("DailyTimesTableViewCell", owner: self, options: nil)?.first as! DailyTimesTableViewCell
cell.endTimeTapped = { [unowned self](_) in
// Use unowned to make sure you don't create a retain-cycle
self.setTimeInDatePicker(time: endTime!, cell: cell)
}
return cell
}
func setTimeInDatePicker(time: String, cell: DailyTimesTableViewCell) {
let row = cell.tag
let rows = self.timesArray.count
if self.startTimeHighlighted{
// Setting minimum startTime for datePicker
if row == 0{ // For first row
let minStartTimeString = "0:05 am"
cell.datePicker.minimumDate = self.convertToDateObject(timeString: minStartTimeString)
}
else if row > 0 { // For remaining rows
let endTimeStringOfPreviousCell = self.timesArray[row - 1]["endTime"]!
let endTimeObjectOfPreviousCell = self.convertToDateObject(timeString: endTimeStringOfPreviousCell)
cell.datePicker.minimumDate = endTimeObjectOfPreviousCell
}
// Setting maximum startTime for datepicker
let endTimeString = self.timesArray[row]["endTime"]!
let endTimeObject = self.convertToDateObject(timeString: endTimeString)
let maxStartTimeObject = endTimeObject.addingTimeInterval(-5 * 60.0) // removing 5mins
cell.datePicker.maximumDate = maxStartTimeObject
// Setting selected date in as startTime title
let dateString = self.convertDateToString(cell.datePicker.date)
cell.startTime.setTitle(dateString, for: .normal)
// Saving updated date to the timesArray
self.timesArray[row]["startTime"] = dateString
//print("endTime in DatePickerChanged: \(self.timesArray[row]["endTime"])")
print("timesArray when startTimeHighlighted: \(self.timesArray)")
}
else if self.endTimeHighlighted{
print("datePicker changed 3")
// Setting minimum endTime for datePicker
let startTimeString = self.timesArray[row]["startTime"]
let startTimeObject = self.convertToDateObject(timeString: startTimeString!)
let minEndTimeObject = startTimeObject.addingTimeInterval(5 * 60.0) // adding 5mins
cell.datePicker.minimumDate = minEndTimeObject
// Setting maximum endTime for datePicker
if rows == 1 || row + 1 == self.timesArray.count{ // For first and last row
let maxEndTimeString = "11:55 pm"
cell.datePicker.maximumDate = self.convertToDateObject(timeString: maxEndTimeString)
}
else{ // If more than one row
let nextCellStartTime = self.timesArray[row + 1]["startTime"]!
let nextCellStartTimeObject = self.convertToDateObject(timeString: nextCellStartTime)
cell.datePicker.maximumDate = nextCellStartTimeObject
}
// Setting selected date in as endTime title
let dateString = self.convertDateToString(cell.datePicker.date)
cell.endTime.setTitle(dateString, for: .normal)
// Saving updated date to the timesArray
self.timesArray[row]["endTime"] = dateString
print("timesArray when endTimeHighlighted: \(self.timesArray)")
}
}
请注意 endTimeTapped 闭包如何使 [unowned self]
的用户避免保留循环。
您还可以注意到 beginUpdate/endUpdate 已被删除。原因是您没有做任何影响相关单元格高度的事情,您只是更改日期,因此您不需要触发 tableView 的刷新,因为更改将自动应用。
检查这是否对您有所帮助?!
注意单元格是一个类,您作为参数发送给 setTimeInDatePicker
的是对它的引用,因此您实际上不需要返回任何东西,所以您已经拥有它。
关于ios - 如何在 cellForRowAt Swift 之外修改单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45063420/
我是一名优秀的程序员,十分优秀!