我需要在UITableView的一行中呈现一个UIStepper(只有第二行 - 见下图)。
因此我实施了func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
,如下所示:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("OptionCell")!
let debugModeOptionType = DebugModeOptionsType(rawValue: indexPath.row)
switch(debugModeOptionType!) {
case .DummyCurrentLocation:
cell.textLabel!.text = "Dummy current location"
case .StepLength:
cell.textLabel!.text = "Step Length: \(stepLength)"
// create a UIStepper
let stepper = UIStepper(frame: CGRectMake(220, 10, 100, 10))
// customize UIStepper
stepper.autorepeat = true
stepper.value = stepLength
stepper.minimumValue = 0.1
stepper.stepValue = 0.02
stepper.maximumValue = 1.5
stepper.addTarget(self, action: #selector(adjustStepLength(_:)), forControlEvents: UIControlEvents.AllEvents)
// add UIStepper into the cell
stepper.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addSubview(stepper)
case .TrueHeading:
cell.textLabel?.text = "True Heading: \(trueHeading)"
case .MagneticHeading:
cell.textLabel?.text = "Magnetic Heading: \(magneticHeading)"
case .HeadingAccuracy:
cell.textLabel?.text = "Heading Accuracy: \(headingAccuracy)"
case .CurrentDirection:
cell.textLabel?.text = "Current Direction: \(currentDirection)"
case .DrawWalking:
cell.textLabel?.text = "Draw walking while navigating"
}
if selectedDebugModeOptions.contains(debugModeOptionType!) {
cell.accessoryType = UITableViewCellAccessoryType.Checkmark
} else {
cell.accessoryType = UITableViewCellAccessoryType.None
}
return cell
}
然而,当我在真实设备上触摸UIStepper时(这在模拟器内部不会发生),会发生以下情况:
当发生这种情况时,其他细胞会出现这种情况。 UISteppers也开始闪烁。为什么会出现这样的问题?
答案 0 :(得分:2)
我不能说为什么这只发生在一个真实的设备上,但是因为表视图单元被重用,所以在以编程方式向单元格添加元素时必须小心,因为这些元素(例如你的步进器)将被传播当细胞被重复使用时,到其他细胞。
至少有两种方法可以解决这个问题:
在将可重复使用的单元格出列后检查是否存在步进器,如果它位于不需要步进器的行上,则将其移除。您可以通过为步进器提供唯一标记号(例如123
),然后使用该标记搜索子视图并将其删除来执行此操作。
let stepperTagNumber = 123
let cell = tableView.dequeueReusableCellWithIdentifier("OptionCell")!
let debugModeOptionType = DebugModeOptionsType(rawValue: indexPath.row)
if let stepper = cell.contentView.viewWithTag(stepperTagNumber) {
// We have a stepper but don't need it, so remove it.
if debugModeOptionType != .StepLength {
stepper.removeFromSuperview()
}
} else {
// We don't have a stepper, but need one.
if debugModeOptionType == .StepLength {
// create a UIStepper
let stepper = UIStepper(frame: CGRectMake(220, 10, 100, 10))
stepper.tag = stepperTagNumber // This is key, don't forget to set the tag
// customize UIStepper
stepper.autorepeat = true
stepper.value = stepLength
stepper.minimumValue = 0.1
stepper.stepValue = 0.02
stepper.maximumValue = 1.5
stepper.addTarget(self, action: #selector(adjustStepLength(_:)), forControlEvents: UIControlEvents.AllEvents)
// add UIStepper into the cell
stepper.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addSubview(stepper)
}
}
OR:
为您的tableview创建第二个原型单元格(称为"OptionCellWithStepper"
)。将步进器添加到故事板中的该单元格。然后,当您致电dequeueReusableCellWithIdentifier
时,请对案例"OptionCellWithStepper"
使用.StepLength
,并对所有其他案例使用标识符"OptionCell"
。这样做,您不必以编程方式添加步进器,也不必记住为其他单元格删除它。
let debugModeOptionType = DebugModeOptionsType(rawValue: indexPath.row)
let cellID = (debugModeOptionType == .StepLength) ? "OptionCellWithStepper" : "OptionCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellID)!