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

如何用SwiftUI实现类似iOS苹果笔记的富文本编辑器

仿iOS苹果笔记的富文本编辑器开发问题

我要做一款和iOS苹果笔记App外观、体验完全一致的富文本编辑器,需要支持动态设置粗体/斜体/下划线/删除线、项目符号及缩进功能。苹果没有提供现成组件,我也不想用第三方库,目前基于UIViewRepresentable、UITextView和NSAttributedString开始开发。

我的思路是获取段落的NSRange,再根据用户选择调整格式,但这种方式太繁琐,尤其是项目符号的实现碰到很多困难。我考虑过用WKWebView,但相关资料极少。另外我注意到苹果笔记的字体大小选项是Title/Heading/Subheading/Body/Monostyle,和iOS系统字体样式不匹配,疑惑它是不是基于HTML实现的?后来发现苹果笔记用的是SF字体的特殊变体,这可能是样式不一致的原因。

目前我的代码只能对后续输入的文本设置粗体等格式,没法像苹果笔记那样作用于整段,也不支持选中内容的格式化,感觉当前的实现方向可能有问题。

以下是我目前的代码:

struct AttributedTextEditor: UIViewRepresentable {
    
    @Binding var text: NSAttributedString
    
    @Binding var bold: Bool
    @Binding var italic: Bool
    @Binding var underline: Bool
    @Binding var strike: Bool

    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        textView.delegate = context.coordinator
        return textView
    }

    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.attributedText = text
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, UITextViewDelegate {
        var parent: AttributedTextEditor

        init(_ parent: AttributedTextEditor) {
            self.parent = parent
        }
        
        func textViewDidChange(_ textView: UITextView) {
            parent.text = NSAttributedString(attributedString: textView.attributedText)
        }
        
        func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
            
            var traits = UIFontDescriptor().symbolicTraits

            if parent.bold {
                traits.insert([.traitBold])
            }
            if parent.italic {
                traits.insert([.traitItalic])
            }
            if parent.underline {
                textView.typingAttributes[NSAttributedString.Key.underlineStyle] = 1
            } else {
                textView.typingAttributes[NSAttributedString.Key.underlineStyle] = 0
            }
            if parent.strike {
                textView.typingAttributes[NSAttributedString.Key.strikethroughStyle] = 1
            } else {
                textView.typingAttributes[NSAttributedString.Key.strikethroughStyle] = 0
            }
            
            let fontDescriptor = UIFontDescriptor().withSymbolicTraits(traits)
            textView.typingAttributes[NSAttributedString.Key.font] = UIFont(descriptor: fontDescriptor!, size: 34)
            return true
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 10:38:25