Tencent / QMUI_iOS

QMUI iOS——致力于提高项目 UI 开发效率的解决方案
http://qmuiteam.com/ios
Other
7.08k stars 1.38k forks source link

crash in QMUITextfiled and QMUITextview #1168

Closed dujj closed 3 years ago

dujj commented 3 years ago

Bug 表现 系统三指撤销, crash 经测试,在微信,斗鱼,等多个应用也会出现此问题

如何重现

  1. 编辑框,设置最大长度
  2. 切换到系统中文输入法
  3. 输入字符到达最大长度后,删掉一个字符,再输入一串拼音(也即产生 markedTextRange)
  4. 三指滑动撤销,crash

预期的表现 不会crash

修复方案: 1、完全屏蔽cut,past,copy方法,似乎不会响应三指撤销 2、以下代码,也可解决,但未充分测试: @implementation _QMUITextFieldDelegator

pragma mark -

其他信息

MoLice commented 3 years ago

无法重现,请明确操作路径、QMUI 版本。

https://user-images.githubusercontent.com/1190261/102886086-6d517880-448f-11eb-875d-6488683abecd.MP4

dujj commented 3 years ago

数字键盘比较容易复现: 字母键盘,适合三指滑动撤销崩溃:

https://user-images.githubusercontent.com/9443889/102967233-72183a00-452c-11eb-9aa2-e92eb4b1c9fd.MP4

MoLice commented 3 years ago
  1. 编辑框,设置最大长度
  2. 切换到系统中文输入法
  3. 输入字符到达最大长度后,删掉一个字符,再输入一串拼音(也即产生 markedTextRange)
  4. 三指滑动撤销,crash

以 QMUITextView 为例,在第4步触发系统的 undo 时,会直接调用 UITextViewTextDidChangeNotification,此时系统的 undoManager 已经记录了当下的文本框操作历史,但由于 QMUITextView 在 handleTextChanged: 里有最长字符限制,需要去修改当前的 text,所以导致系统记录完文本操作历史后又产生了新的、不被记录的文本变化,于是最终执行 undo 时数据前后不匹配,crash。

新版本会修复该问题,在此之前可以先将以下代码添加到 -[QMUITextView handleTextChanged:] 方法内临时修复:

if (textView.maximumTextLength < NSUIntegerMax && textView.undoManager.undoing) {
    return;
}

对于 QMUITextField 临时修复代码相同:

if (textField.maximumTextLength < NSUIntegerMax && textField.undoManager.undoing) {
    return;
}
dujj commented 3 years ago

https://user-images.githubusercontent.com/9443889/102985941-f37ec500-454a-11eb-9af0-8091eda52ec3.MP4

上述修改方案,数字键盘,按新步骤,还是crash

dujj commented 3 years ago

目前线上微信也是crash的

https://user-images.githubusercontent.com/9443889/102986080-2e80f880-454b-11eb-97f0-b159fd4a9baf.MP4

dujj commented 3 years ago

只要有最大长度设置的,数字键盘的编辑框,不管什么app,几乎都会崩溃,已经测试过微信,斗鱼,都crash

MoLice commented 3 years ago

上述修改方案,数字键盘,按新步骤,还是crash

无法重现

MoLice commented 3 years ago

已发布 4.2.2 修复该问题。