2

I have a UITableView with cells that have swappable UIContextualActions to delete or rename (edit) individual cell's TextFields.

Since I made the switch to Swift 5 / iOS 13, triggering the rename UIContextualAction on these cells causes the keyboard to launch and instantly dismiss before the user has a chance to type. Not only does the keyboard go away, the particular cell I'm trying to edit becomes completely empty, and the following warning gets generated:

[Snapshotting] Snapshotting a view (0x10c90a470, _UIReplicantView) that has not been rendered at least once requires afterScreenUpdates:YES.

Below is the code for the rename UIContextualAction:

let actionRename = UIContextualAction(style: .normal, title: "") { (action, view, completionHandler) in

      let cell = self.tableLayers.cellForRow(at: indexPath) as! LayerUITableViewCell
      cell.layerTitle.isEnabled = true // enable UITextField editing
      cell.layerTitle.becomeFirstResponder() // launch keyboard
      cell.layerTitle.selectedTextRange = cell.layerTitle.textRange(from: (cell.layerTitle.beginningOfDocument), to: (cell.layerTitle.endOfDocument)) // select all text
      completionHandler(true)

} // end of let actionRename

I'm guessing the animation of the UIContextual action is somehow triggering the keyboard's resignFirstResponder.

To summarize, prior to swift 5/iOS 13, the order of events went something like this:

  1. user swipes cell left/right
  2. user hits UIContextual button
  3. cell returns to center
  4. text gets selected
  5. keyboard launches
  6. user types, hits return
  7. keyboard resignFirstResponder

Whereas the behavior I'm seeing after the migration looks like this:

  1. user swipes cell left/right
  2. user hits UIContextual button
  3. text gets selected
  4. keyboard launches
  5. cell returns to center (which somehow triggers resignFirstResponder)
  6. keyboard resignFirstResponder

Update 2019/10/02

I have confirmed that it's the cell animation that is causing the premature keyboard dismissal. If I introduce a delay after the completionHandler as follows:

let actionRename = UIContextualAction(style: .normal, title: "") { (action, view, completionHandler) in

      completionHandler(true)
      self.perform(#selector(self.layerRenameDos), with: nil, afterDelay: 1.0)   
      // layerRenameDos has the editing/firstResponder code from above

    } // end of let actionRename

With this change, the cell animates back to center, keyboard launches, and I'm able to type away. This, however, is obviously a hacky work-around. Any suggestions would be appreciated

Plutovman
  • 677
  • 5
  • 22

1 Answers1

1

I think this is a better solution. Just be sure to execute your code on the next runloop.

CATransaction.begin()
CATransaction.setCompletionBlock {
   DispatchQueue.main.async {
     //your code on the next runloop after the animation has finished
   }
}
complitionHandler(true)
// or tableView.setEditing(false, animated: true)
CATransaction.commit()
Stefo
  • 636
  • 1
  • 8
  • 13
  • I implemented the changes, but saw no difference. Perhaps I don't understand what you mean by 'next loop'. Can you explain? Thank you. – Plutovman Nov 25 '19 at 00:45