Skip to content

Repository files navigation

AITextView - 强大的iOS富文本编辑器与AI输出组件

一个功能完整的iOS富文本编辑器框架,支持UIKit和SwiftUI,同时可作为AI流式输出的完美展示组件

Version Platform Swift License

📋 目录

🎥 功能演示

富文本编辑功能

富文本编辑功能演示

AI输出功能演示

AI输出功能演示

🎯 项目简介

AITextView 是一个专为iOS应用设计的强大富文本编辑器框架,基于WebKit技术构建,提供了完整的富文本编辑功能。该框架采用混合架构设计,既保持了Web技术的强大编辑能力,又确保了原生iOS应用的性能和用户体验。

🎨 双UI框架支持

  • UIKit集成: 提供完整的UIKit组件,无缝集成到传统iOS项目中
  • SwiftUI支持: 原生SwiftUI组件,完美适配现代iOS开发架构
  • 统一API: 两套UI框架共享相同的核心功能,确保开发体验一致性

🤖 AI内容生成载体

  • 流式输出: 专为AI内容生成优化,支持实时流式文本输出
  • 格式保持: AI生成的内容自动保持富文本格式,支持代码高亮、列表等

主要优势

  • 🚀 高性能: 基于WebKit,支持大量文本和复杂格式
  • 🎨 功能丰富: 支持所有主流富文本格式和编辑操作
  • 🔄 双框架支持: 同时支持UIKit和SwiftUI
  • 📱 原生体验: 完美集成iOS键盘和系统功能
  • 🛠️ 高度可定制: 灵活的配置选项和扩展能力
  • 🌙 暗黑模式: 完整支持iOS暗黑模式
  • 🤖 AI友好: 完美适配AI流式输出场景

🛠️ 核心特性

文本格式化

  • 基础格式: 粗体、斜体、下划线、删除线
  • 文本样式: 字体大小、颜色、背景色
  • 文本对齐: 左对齐、居中、右对齐、两端对齐
  • 缩进控制: 增加/减少缩进

结构化内容

  • 标题级别: H1-H6 六级标题
  • 列表支持: 有序列表、无序列表、嵌套列表
  • 引用块: 支持引用格式
  • 代码块: 内联代码和代码块

媒体支持

  • 图片插入: 支持相册选择和拍照
  • 链接插入: 自动识别和格式化链接
  • 表格支持: 创建和编辑表格

编辑功能

  • 撤销/重做: 完整的操作历史管理
  • 复制/粘贴: 支持富文本格式保持
  • 全选/清除: 快速选择操作
  • 自适应高度: 根据内容自动调整高度

用户体验

  • 键盘工具栏: 自定义键盘上方工具栏
  • 焦点管理: 智能焦点切换和保持
  • 滚动优化: 平滑的滚动体验
  • 触摸优化: 响应式触摸交互

🎭 双重用途

1. 富文本编辑器

AITextView 可以作为功能完整的富文本编辑器使用,支持:

  • 所见即所得编辑
  • 丰富的格式化选项
  • 媒体内容插入
  • 实时预览

2. AI输出组件

AITextView 特别适合作为AI应用的输出展示组件:

  • 流式输出支持: 实时显示AI生成的内容
  • HTML格式渲染: 完美支持AI返回的HTML格式内容
  • 富文本展示: 支持AI生成的各种格式(标题、列表、代码块等)
  • 只读模式: 可设置为只读模式,专门用于内容展示
  • 动态更新: 支持内容的动态追加和更新

🏗️ 项目架构

架构层次说明

1. 用户接口层

  • 支持 UIKitSwiftUI 两种使用方式
  • 提供灵活的集成选择

2. SwiftUI包装层

  • SwiftUIAITextView: SwiftUI版本的编辑器包装器
  • SwiftUIAITextToolbar: SwiftUI版本的工具栏包装器
  • AITextViewState: 用于状态管理的ObservableObject

3. UIKit核心层

  • AITextView: 核心编辑器组件,继承自UIView
  • AITextToolbar: 可滚动的工具栏,包含各种编辑操作按钮
  • AITextWebView: WKWebView的简单包装器

4. 前端实现层

  • rich_editor.html: 基础HTML结构,包含可编辑的div
  • rich_editor.js: JavaScript逻辑,实现所有富文本编辑功能
  • style.css + normalize.css: 样式定义和浏览器兼容性

🔄 关键工作原理

JavaScript-Native通信机制

  1. Swift → JavaScript: 通过webView.evaluateJavaScript()调用JS函数
  2. JavaScript → Swift: 通过回调URL (re-callback://) 触发Swift代理方法
  3. 命令队列: JS将多个操作打包成JSON命令队列,Swift批量处理

代理模式

  • AITextViewDelegate: 处理编辑器事件(内容变化、焦点变化、高度变化)
  • AITextToolbarDelegate: 处理需要原生UI的操作(颜色选择、图片插入)

🚀 快速开始

系统要求

  • iOS 12.0+
  • Swift 5.7+
  • Xcode 14.0+

安装方式

Swift Package Manager (推荐)

  1. 在Xcode中选择 FileAdd Package Dependencies
  2. 输入仓库URL: https://github.com/youyinian288/AITextView.git
  3. 选择版本并添加到项目

CocoaPods

pod 'AITextView', '~> 4.3.0'

手动安装

  1. 下载项目源码
  2. AITextView/Sources 文件夹拖入项目
  3. 确保添加了所有资源文件

📱 使用示例

UIKit 使用方式

import UIKit
import AITextView

class ViewController: UIViewController {
    @IBOutlet var editorView: AITextView!
    @IBOutlet var toolbar: AITextToolbar!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 设置编辑器
        editorView.delegate = self
        editorView.placeholder = "请输入内容..."
        editorView.html = "<p>Hello <b>World</b>!</p>"
        
        // 设置工具栏
        toolbar.editor = editorView
        toolbar.options = AITextDefaultOption.all
    }
}

extension ViewController: AITextViewDelegate {
    func aiTextView(_ editor: AITextView, contentDidChange content: String) {
        print("内容变化: \(content)")
    }
    
    func aiTextView(_ editor: AITextView, heightDidChange height: Int) {
        print("高度变化: \(height)")
    }
}

SwiftUI 使用方式

import SwiftUI
import AITextView

struct ContentView: View {
    @StateObject private var editorState = AITextViewState(
        htmlContent: "<p>Hello <b>World</b>!</p>",
        placeholder: "请输入内容..."
    )
    
    var body: some View {
        VStack(spacing: 0) {
            // 编辑器
            SwiftUIAITextView(
                state: editorState,
                onContentChange: { content in
                    print("内容变化: \(content)")
                },
                onHeightChange: { height in
                    print("高度变化: \(height)")
                }
            )
            .frame(minHeight: 200)
            
            // 工具栏
            SwiftUIAITextToolbar(
                state: editorState,
                options: AITextDefaultOption.all
            )
            .frame(height: 44)
            
            // HTML预览
            ScrollView {
                Text(editorState.htmlContent)
                    .font(.system(.caption, design: .monospaced))
                    .padding()
            }
            .background(Color(.systemGray6))
        }
    }
}

自定义工具栏选项

// 创建自定义工具栏选项
let customOptions: [AITextOption] = [
    AITextDefaultOption.bold,
    AITextDefaultOption.italic,
    AITextDefaultOption.underline,
    AITextDefaultOption.strikeThrough,
    AITextDefaultOption.undo,
    AITextDefaultOption.redo
]

toolbar.options = customOptions

处理图片插入

extension ViewController: AITextToolbarDelegate {
    func aiTextToolbar(_ toolbar: AITextToolbar, shouldInsertImage image: UIImage) {
        // 处理图片插入逻辑
        let imageData = image.jpegData(compressionQuality: 0.8)
        let base64String = imageData?.base64EncodedString() ?? ""
        let html = "<img src='data:image/jpeg;base64,\(base64String)' />"
        
        editorView.insertHTML(html)
    }
}

🤖 AI集成指南

作为AI输出组件使用

AITextView 特别适合作为AI应用的输出展示组件,支持流式输出和富文本渲染:

1. 基础AI输出设置

class AIViewController: UIViewController {
    @IBOutlet var aiOutputView: AITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 设置为只读模式,专门用于AI输出展示
        aiOutputView.editingEnabled = false
        aiOutputView.placeholder = "AI正在思考中..."
        
        // 设置初始内容
        aiOutputView.html = "<h2>🤖 AI助手</h2><p>请提出您的问题...</p>"
    }
}

2. 流式输出实现

import SwiftOpenAI

class AIStreamController: UIViewController {
    private var aiOutputView: AITextView!
    private var currentMessage: String = ""
    
    private func startAIStream(prompt: String) {
        // 清空之前的内容
        currentMessage = ""
        aiOutputView.html = "<h3>💬 AI回复</h3><p>正在生成回复...</p>"
        
        // 创建OpenAI服务
        let service = OpenAIServiceFactory.service(
            apiKey: "your-api-key",
            overrideBaseURL: "https://api.deepseek.com"
        )
        
        let parameters = ChatCompletionParameters(
            messages: [.init(role: .user, content: .text("请用HTML格式返回富文本内容,问题:" + prompt))],
            model: .custom("deepseek-chat")
        )
        
        Task {
            do {
                let stream = try await service.startStreamedChat(parameters: parameters)
                
                for try await result in stream {
                    await MainActor.run {
                        let content = result.choices?.first?.delta?.content ?? ""
                        self.currentMessage += content
                        
                        // 实时更新显示
                        self.updateAIOutput()
                    }
                }
            } catch {
                await MainActor.run {
                    self.showError(error.localizedDescription)
                }
            }
        }
    }
    
    private func updateAIOutput() {
        let htmlContent = """
        <div style="background-color: #f8f9fa; border-left: 4px solid #28a745; padding: 12px; margin: 8px 0; border-radius: 4px;">
            <h4 style="color: #28a745; margin: 0 0 8px 0;">💬 AI回复</h4>
            <div style="margin: 0; color: #333; line-height: 1.6;">\(currentMessage)</div>
        </div>
        """
        
        aiOutputView.html = htmlContent
    }
}

3. SwiftUI AI输出组件

struct AIOutputView: View {
    @StateObject private var aiState = AITextViewState(
        htmlContent: "<h2>🤖 AI助手</h2>",
        placeholder: "AI正在思考中..."
    )
    
    var body: some View {
        SwiftUIAITextView(
            state: aiState,
            editingEnabled: false, // 只读模式
            onContentChange: { content in
                // 处理内容变化
            }
        )
        .frame(minHeight: 300)
        .background(Color(.systemBackground))
    }
    
    func updateAIResponse(_ response: String) {
        aiState.htmlContent = """
        <div style="padding: 16px; background-color: #f8f9fa; border-radius: 8px;">
            <h3 style="color: #28a745;">🤖 AI回复</h3>
            <div style="margin-top: 12px; line-height: 1.6;">\(response)</div>
        </div>
        """
    }
}

支持的AI服务

AITextView 可以与多种AI服务集成:

  • OpenAI GPT系列
  • DeepSeek
  • Claude (通过OpenRouter)
  • Gemini
  • 本地模型 (Ollama)
  • 其他兼容OpenAI API的服务

🤝 贡献指南

我们欢迎社区贡献!请遵循以下步骤:

  1. Fork 项目
  2. 创建功能分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 打开 Pull Request

开发环境设置

  1. 克隆仓库
  2. 打开 AITextView.xcodeproj
  3. 选择目标设备或模拟器
  4. 运行项目

📄 许可证

本项目采用 BSD 3-Clause 许可证 - 查看 LICENSE.md 文件了解详情。

🙏 致谢

  • 感谢所有贡献者的努力
  • 基于 RichEditorView 项目进行改进
  • 感谢开源社区的支持
  • 特别感谢 SwiftOpenAI 项目提供的AI集成支持

📞 联系方式


AITextView - 让富文本编辑和AI输出变得简单而强大! 🚀

🎯 使用场景

富文本编辑器场景

  • 📝 笔记应用
  • 📰 内容管理系统
  • 📧 邮件编辑器
  • 📄 文档编辑器
  • 💬 聊天应用(富文本消息)

AI输出组件场景

  • 🤖 AI聊天应用
  • 📊 AI内容生成工具
  • 🎓 AI教育应用
  • 💡 AI写作助手
  • 🔍 AI搜索结果显示

选择 AITextView,为您的iOS应用提供强大的富文本编辑和AI输出能力!

About

A feature-complete iOS rich text editor framework supporting both UIKit and SwiftUI, perfect for AI streaming output display. Built on WebKit with native performance.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages