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

如何实现类似Apple Notes的文本选中后加粗等格式设置功能?

问题描述

我正在开发一款笔记应用,想要实现类似Apple Notes的文本格式化功能——用户选中部分文本后,可为选中内容设置加粗、下划线、删除线或斜体,但目前没能实现该功能。

我尝试使用UITextView作为文本编辑器,通过.selectedRange检测选中的文本范围,将字符串转换为NSMutableAttributedString后在UILabel上显示,但除了初始化UILabel时,无法为NSMutableAttributedString添加属性。

UITextView封装代码

struct UITextViewRepresentable: UIViewRepresentable {
    let textView = UITextView()
    @Binding var text: String
    @Binding var selectedRange: NSRange
    
    func makeUIView(context: Context) -> UITextView {
        textView.delegate = context.coordinator
        return textView
    }
    
    func updateUIView(_ uiView: UITextView, context: Context) {
        // SwiftUI -> UIKit
        uiView.text = text
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(text: $text, selectedRange: $selectedRange)
    }
    
    class Coordinator: NSObject, UITextViewDelegate {
        @Binding var text: String
        @Binding var selectedRange: NSRange
        
        init(text: Binding<String>, selectedRange: Binding<NSRange>) {
            self._text = text
            self._selectedRange = selectedRange
        }
        
        func textViewDidChange(_ textView: UITextView) {
            // UIKit -> SwiftUI
            _text.wrappedValue = textView.text
        }
        
        func textViewDidChangeSelection(_ textView: UITextView) {
            // 每次用户修改选中范围时触发
            selectedRange = textView.selectedRange
        }
    }
}

UILabel封装代码

struct AttributedText: UIViewRepresentable {
    
    let attributedString: NSMutableAttributedString
    
    init(_ attributedString: NSMutableAttributedString) {
        self.attributedString = attributedString
        attributedString.addAttribute(.foregroundColor, value: UIColor.red, range: NSRange(location: 7, length: 5))
    }
    
    func makeUIView(context: Context) -> UILabel {
        let label = UILabel()
        
        label.lineBreakMode = .byClipping
        label.numberOfLines = 0

        return label
    }
    
    func updateUIView(_ uiView: UILabel, context: Context) {
        uiView.attributedText = attributedString
    }
}

ContentView代码

struct ContentView: View {
    @State private var text = "placeholder text in UITextView"
    var attributedText: NSMutableAttributedString {
        return NSMutableAttributedString(string: self.text)
    }
    @State private var selectedRange = NSRange(location: 0, length: 0)
    var body: some View {
            VStack {
                UITextViewRepresentable(text: $text, selectedRange: $selectedRange)
                AttributedText(attributedText)
            }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:15:20