You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS16中如何为UITextView添加正则表达式查找选项及配置参数

基于UITextView.findInteraction实现正则表达式查找

核心配置与选项处理

1. 区分默认UIAction

系统默认的查找选项(大小写敏感、全词匹配等)对应的UIAction,可通过UITextFindInteraction.ActionIdentifier枚举识别:

  • 大小写敏感:UITextFindInteraction.ActionIdentifier.caseSensitive
  • 全词匹配:UITextFindInteraction.ActionIdentifier.wholeWord

在optionsMenuProvider闭包中,遍历默认菜单的子元素即可定位这些系统内置action。

2. 排除默认选项

若不需要某个默认选项,直接从action数组中移除后重新构建菜单:

textView.findInteraction?.optionsMenuProvider = { defaultMenu in
    var updatedActions = defaultMenu.children.compactMap { $0 as? UIAction }
    // 移除全词匹配选项
    updatedActions.removeAll { $0.identifier == UITextFindInteraction.ActionIdentifier.wholeWord }
    return UIMenu(title: "", children: updatedActions)
}

3. 修改默认选项状态与逻辑

如需调整默认选项的初始状态或自定义触发逻辑,可替换原action的handler:

private var currentSearchOptions: UITextSearchOptions = []
private var currentSearchText = ""

// 在optionsMenuProvider中处理大小写敏感选项
if let caseSensitiveIndex = updatedActions.firstIndex(where: { $0.identifier == UITextFindInteraction.ActionIdentifier.caseSensitive }) {
    let originalAction = updatedActions[caseSensitiveIndex]
    // 保留原标识与标题,替换处理逻辑
    let customCaseAction = UIAction(
        title: originalAction.title,
        image: originalAction.image,
        identifier: originalAction.identifier,
        state: .on // 设置默认开启
    ) { [weak self] action in
        self?.currentSearchOptions.toggle(.caseInsensitive)
        self?.performSearch(with: self?.currentSearchText ?? "")
    }
    updatedActions[caseSensitiveIndex] = customCaseAction
}

添加正则查找选项

1. 自定义正则选项Action

在optionsMenuProvider中添加正则匹配开关:

private var isRegexSearchEnabled = false

// 加入自定义正则选项
let regexAction = UIAction(title: "正则匹配", state: .off) { [weak self] action in
    self?.isRegexSearchEnabled = action.state == .on
    self?.performSearch(with: self?.currentSearchText ?? "")
}
updatedActions.append(regexAction)

2. 实现正则查找逻辑

自定义搜索方法,根据正则开关切换查找方式:

private func performSearch(with text: String) {
    currentSearchText = text
    guard isRegexSearchEnabled, !text.isEmpty else {
        // 非正则模式使用系统默认查找
        textView.findInteraction?.search(for: text, options: currentSearchOptions)
        return
    }
    
    // 正则查找逻辑
    do {
        let regexOptions: NSRegularExpression.Options = currentSearchOptions.contains(.caseInsensitive) ? .caseInsensitive : []
        let regex = try NSRegularExpression(pattern: text, options: regexOptions)
        let fullTextRange = NSRange(textView.text.startIndex..., in: textView.text)
        let matches = regex.matches(in: textView.text, options: [], range: fullTextRange)
        
        // 转换为系统要求的UITextFindMatch格式
        let findMatches = matches.map { match in
            let startPos = textView.position(from: textView.beginningOfDocument, offset: match.range.location)!
            let endPos = textView.position(from: startPos, offset: match.range.length)!
            return UITextFindMatch(range: match.range, textRange: textView.textRange(from: startPos, to: endPos)!)
        }
        
        // 更新查找结果到findInteraction
        textView.findInteraction?.update(with: findMatches, for: text, options: currentSearchOptions)
    } catch {
        // 正则格式错误,返回空结果
        textView.findInteraction?.update(with: [], for: text, options: currentSearchOptions)
    }
}

关键注意点

  • UITextSearchOptions需自行维护,系统不会自动同步选项菜单状态,需在action的handler中手动更新。
  • 自定义查找后,必须调用findInteraction?.update(with:for:options:)将结果同步到系统查找界面。
  • 需处理正则表达式的格式错误,避免非法正则导致崩溃。

内容的提问来源于stack exchange,提问作者Nickkk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 23:50:27