循环调用deleteBackward()仅删除1个字符的问题求解
问题原因
你写的循环计数逻辑本身没有错误,运行时确实执行了5次proxy.deleteBackward()调用,最终仅删除1个字符的核心原因是:deleteBackward()是UIKit文本输入体系的响应方法,并非同步生效的即时操作:调用该方法只是向当前第一响应者的文本输入系统投递一个删除请求,实际的字符删除、UI刷新逻辑,必须等主线程RunLoop执行完当前代码块、进入下一轮事件处理阶段才会执行。
你在同一个同步执行的代码块、同一个RunLoop周期内连续投递5个删除请求,系统不会逐次响应处理,只会生效最后一次请求,因此最终只删除了1个字符,整个过程也不会抛出任何运行时错误。
修改方案
不要用同步循环连续调用删除方法,需要给每次删除操作留出主线程处理事件的间隙,两种常用实现方式如下:
- 递归异步调度:每次删除操作投递到主队列执行完成后,再发起下一次删除,保证前一次操作完全生效
func deleteCharacters(count: Int) { guard count > 0 else { return } proxy.deleteBackward() DispatchQueue.main.async { [weak self] in self?.deleteCharacters(count: count - 1) } } // 调用方法,执行5次删除 deleteCharacters(count: 5) - 直接操作文本内容:如果业务场景允许,直接读取当前输入的文本,一次性移除末尾5个字符后回写,不需要逐次调用UI响应方法,执行效率更高
if let currentText = proxy.documentContextBeforeInput { let deleteLength = min(5, currentText.count) let targetText = String(currentText.dropLast(deleteLength)) // 替换原有文本完成删除 proxy.text = targetText }
内容的提问来源于stack exchange,提问作者Dennislay
相关产品推荐
相关产品推荐

