基于SwiftUI UIViewRepresentable实现带自定义ID的隐藏<del>标签删除线功能
自定义文本编辑器实现思路
针对你提出的两个核心问题,以下是具体的实现方向:
一、隐藏标签但保留删除线与自定义ID功能
不要将标签作为可见文本插入编辑器,而是把它转为不可见的属性标记,仅在内容导出/持久化时还原标签格式:
- 用
NSAttributedString的自定义属性存储标签的ID:定义一个自定义Key,比如let customDelIDKey = NSAttributedString.Key(rawValue: "CustomDelTagID"),给需要标记为删除的文本范围附加该属性,值设为你的自定义ID字符串。 - 编辑器显示时,仅给目标文本添加删除线样式:通过
NSAttributedString.Key.strikethroughStyle设置为NSUnderlineStyle.single.rawValue,完全不渲染标签的文本内容。 - 内容解析/导出时,遍历
NSAttributedString的属性范围,将带有customDelIDKey属性的文本段用<del id="xxx">...</del>包裹后输出。 - 替换原有的正则匹配逻辑:之前如果是匹配文本中的
标签来加属性,现在改为解析原始带标签的内容时,先剥离标签,只保留中间文本,同时给这段文本附加删除线和自定义ID属性。
二、修改删除键行为为选区左移
通过拦截UITextView的编辑事件,替换默认删除逻辑:
- 实现
UITextViewDelegate的textView(_:shouldChangeTextIn:replacementText:)方法:- 判断当前操作是否为删除键触发:当
replacementText.isEmpty时,即为删除操作(针对退格左移需求处理)。 - 处理选中状态:如果当前
textView.selectedRange.length > 0,先给选中范围的文本添加删除线和自定义ID属性(对应你要的包裹标签逻辑),然后将选区设置为NSMakeRange(range.location, 0),实现选区左移到选中内容的开头。 - 处理光标状态:如果当前没有选中内容(
selectedRange.length == 0),则将选区位置调整为max(0, textView.selectedRange.location - 1),保持长度为0,实现光标左移。 - 最后返回
false,阻止UITextView执行默认的删除操作。
- 判断当前操作是否为删除键触发:当
- 边界处理:当光标已经在文本最开头(
selectedRange.location == 0)时,不执行左移操作,避免越界。
内容的提问来源于stack exchange,提问作者Stefano Vet
相关产品推荐
相关产品推荐

