选择单元格时,UITableViewCell 中的 UISwitch 会冻结应用程序,不会在 UISwitch 切换时冻结
UISwitch in UITableViewCell freezes app when cell is selected, doesn't freeze on UISwitch toggle
我有一个 UITableView,其中我以编程方式为某些单元格添加了一个 UISwitch 作为 accessoryView。对于委托方法 didSelectRowAtIndexPath
,我使用以下方法:tableView.deselectRowAtIndexPath(indexPath, animated: true)
立即,如果单元格是自定义的 class,我会执行一些额外的操作(expanding/collapsing)- UISwitch 不是自定义class,它是常规单元格的附件视图,因此tableView.deselectRowAtIndexPath(indexPath, animated: true)
在单击单元格时执行,仅此而已。问题是,对于将 UISwitch 作为 accessoryView 的单元格,如果你切换开关 on/off 它工作正常 - 但当你按下同一单元格上的其他任何地方时,它会保持突出显示并且应用程序冻结。为什么会发生这种情况,我该如何预防?
didSelectRowAtIndexPath 函数:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
// Deselect automatically if the cell is a DatePickerCell/PickerCell.
let cell = self.tableView(tableView, cellForRowAtIndexPath: indexPath)
if (cell.isKindOfClass(DatePickerCell)) {
let datePickerTableViewCell = cell as! DatePickerCell
datePickerTableViewCell.selectedInTableView(tableView)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
} else if(cell.isKindOfClass(PickerCell)) {
let pickerTableViewCell = cell as! PickerCell
pickerTableViewCell.selectedInTableView(tableView)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
我将开关设置如下:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as UITableViewCell
let row = indexPath.row
allDaySwitch.on = false
gstSwitch.on = false
//Assigns UISwitch cells and UITextField cells
if(indexPath.section == 0) {
let rowTitle = mainOptions[row]
cell.textLabel?.text = rowTitle
cell.accessoryView = nil
} else if(indexPath.section == 1) {
let rowTitle = dateOptions[row]
if(rowTitle == "All Day") {
cell.accessoryView = allDaySwitch
} else {
cell.accessoryView = nil
}
cell.textLabel?.text = rowTitle
} else if(indexPath.section == 2) {
let rowTitle = alertOptions[row]
cell.accessoryView = nil
cell.textLabel?.text = rowTitle
} else {
let rowTitle = billingOptions[row]
if(rowTitle == "Tax Included") {
cell.accessoryView = gstSwitch
} else {
cell.accessoryView = nil
}
cell.textLabel?.text = rowTitle
}
return cell
}
selectedInTableView 函数:
public func selectedInTableView(tableView: UITableView) {
expanded = !expanded
UIView.transitionWithView(rightLabel, duration: 0.25, options:UIViewAnimationOptions.TransitionCrossDissolve, animations: { () -> Void in
self.rightLabel.textColor = self.expanded ? self.tintColor : self.rightLabelTextColor
}, completion: nil)
tableView.beginUpdates()
tableView.endUpdates()
}
您不需要在 didSelectRowAtIndexPath
中调用 cellForRowAtIndexPath
,它已经在您的 dataSource
方法中设置。看起来您在 cellForRowAtIndexPath
中使用静态单元格,您可以轻松地对 didSelectRowAtIndexPath
.
执行相同的操作
switch indexPath.row {
case 0:
// do Something
case 1:
// do Something
default: break
}
此外,问题是您传递的 tableView
实际上并没有被 UITableViewCell
正确访问。 beginUpdates
和 endUpdates
应该在你的视图控制器上调用,因为你的 UITableViewCell 不知道(也不关心)你的 tableView 本身发生了什么。
我有一个 UITableView,其中我以编程方式为某些单元格添加了一个 UISwitch 作为 accessoryView。对于委托方法 didSelectRowAtIndexPath
,我使用以下方法:tableView.deselectRowAtIndexPath(indexPath, animated: true)
立即,如果单元格是自定义的 class,我会执行一些额外的操作(expanding/collapsing)- UISwitch 不是自定义class,它是常规单元格的附件视图,因此tableView.deselectRowAtIndexPath(indexPath, animated: true)
在单击单元格时执行,仅此而已。问题是,对于将 UISwitch 作为 accessoryView 的单元格,如果你切换开关 on/off 它工作正常 - 但当你按下同一单元格上的其他任何地方时,它会保持突出显示并且应用程序冻结。为什么会发生这种情况,我该如何预防?
didSelectRowAtIndexPath 函数:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
// Deselect automatically if the cell is a DatePickerCell/PickerCell.
let cell = self.tableView(tableView, cellForRowAtIndexPath: indexPath)
if (cell.isKindOfClass(DatePickerCell)) {
let datePickerTableViewCell = cell as! DatePickerCell
datePickerTableViewCell.selectedInTableView(tableView)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
} else if(cell.isKindOfClass(PickerCell)) {
let pickerTableViewCell = cell as! PickerCell
pickerTableViewCell.selectedInTableView(tableView)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
我将开关设置如下:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as UITableViewCell
let row = indexPath.row
allDaySwitch.on = false
gstSwitch.on = false
//Assigns UISwitch cells and UITextField cells
if(indexPath.section == 0) {
let rowTitle = mainOptions[row]
cell.textLabel?.text = rowTitle
cell.accessoryView = nil
} else if(indexPath.section == 1) {
let rowTitle = dateOptions[row]
if(rowTitle == "All Day") {
cell.accessoryView = allDaySwitch
} else {
cell.accessoryView = nil
}
cell.textLabel?.text = rowTitle
} else if(indexPath.section == 2) {
let rowTitle = alertOptions[row]
cell.accessoryView = nil
cell.textLabel?.text = rowTitle
} else {
let rowTitle = billingOptions[row]
if(rowTitle == "Tax Included") {
cell.accessoryView = gstSwitch
} else {
cell.accessoryView = nil
}
cell.textLabel?.text = rowTitle
}
return cell
}
selectedInTableView 函数:
public func selectedInTableView(tableView: UITableView) {
expanded = !expanded
UIView.transitionWithView(rightLabel, duration: 0.25, options:UIViewAnimationOptions.TransitionCrossDissolve, animations: { () -> Void in
self.rightLabel.textColor = self.expanded ? self.tintColor : self.rightLabelTextColor
}, completion: nil)
tableView.beginUpdates()
tableView.endUpdates()
}
您不需要在 didSelectRowAtIndexPath
中调用 cellForRowAtIndexPath
,它已经在您的 dataSource
方法中设置。看起来您在 cellForRowAtIndexPath
中使用静态单元格,您可以轻松地对 didSelectRowAtIndexPath
.
switch indexPath.row {
case 0:
// do Something
case 1:
// do Something
default: break
}
此外,问题是您传递的 tableView
实际上并没有被 UITableViewCell
正确访问。 beginUpdates
和 endUpdates
应该在你的视图控制器上调用,因为你的 UITableViewCell 不知道(也不关心)你的 tableView 本身发生了什么。