UITableViewCell中的UIStepper在点击时会出现问题

时间:2016-04-03 06:17:19

标签: ios swift uitableview

我需要在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时(这在模拟器内部不会发生),会发生以下情况:

UIStepper inside UITableViewCell

当发生这种情况时,其他细胞会出现这种情况。 UISteppers也开始闪烁。为什么会出现这样的问题?

1 个答案:

答案 0 :(得分:2)

我不能说为什么这只发生在一个真实的设备上,但是因为表视图单元被重用,所以在以编程方式向单元格添加元素时必须小心,因为这些元素(例如你的步进器)将被传播当细胞被重复使用时,到其他细胞。

至少有两种方法可以解决这个问题:

  1. 在将可重复使用的单元格出列后检查是否存在步进器,如果它位于不需要步进器的行上,则将其移除。您可以通过为步进器提供唯一标记号(例如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:

  2. 为您的tableview创建第二个原型单元格(称为"OptionCellWithStepper")。将步进器添加到故事板中的该单元格。然后,当您致电dequeueReusableCellWithIdentifier时,请对案例"OptionCellWithStepper"使用.StepLength,并对所有其他案例使用标识符"OptionCell"。这样做,您不必以编程方式添加步进器,也不必记住为其他单元格删除它。

    let debugModeOptionType = DebugModeOptionsType(rawValue: indexPath.row)
    let cellID = (debugModeOptionType == .StepLength) ? "OptionCellWithStepper" : "OptionCell"
    let cell = tableView.dequeueReusableCellWithIdentifier(cellID)!