iOS_折叠展开 FoldTextView

1. 显示效果

Test1:直接使用:


Test2:在 cell 里使用:

2. 使用

2.1 直接使用

swift 复制代码
// 1.1 init view
private lazy var mooFoldTextView: MOOFoldTextView = {
    let view = MOOFoldTextView(frame: .zero)
    view.backgroundColor = .cyan
    view.mooDelegate = self
    return view
}()
// 1.2 init conifg
private lazy var attributeTextConfig: MOOFoldTextConfig = {
    let config = MOOFoldTextConfig()
    config.allText =
    """
    Swift is a type-safe language, which means the language helps you to be clear about\
     the types of values your code can work with. If part of your code requires a String,\
    type safety prevents you from passing it an Int by mistake. Likewise, type safety\
    prevents you from accidentally passing an optional String
    """
    config.paragraph.lineSpacing = 10.0
    config.contentWidth = CGRectGetWidth(self.view.bounds)
    return config
}()


// 2.1 add to super view
self.view.addSubview(self.mooFoldTextView)
// 2.2 set config and reload
self.mooFoldTextView.mooConfig = self.mooFoldTextConfig
self.mooFoldTextView.mooReloadText()

// 3 set frame
self.mooFoldTextView.frame = CGRect(x: 0.0,
                                    y: 100.0,
                                    width: CGRectGetWidth(self.view.bounds),
                                    height: self.mooFoldTextConfig.mooCurrentHeight())
       
// 4 Implement Proxy
extension MOOTest1ViewController: MOOFoldTextViewDelegate {
    func mooFoldViewShouldUpdateLayout(_ foldTextView: MOOFoldTextView) {
        // update layout after fold state changed
        self.view.setNeedsLayout()
    }
}         

2.2 在 cell 中使用

2.2.1 at Custom TableViewCell
swift 复制代码
// 1.1 init
private lazy var attributeTextView: MOOFoldTextView = {
    let view = MOOFoldTextView(frame: .zero)
    view.backgroundColor = .cyan
    view.mooDelegate = self
    return view
}()
// 1.2 add to super view
self.contentView.addSubview(self.attributeTextView)
// 1.3 set frame
self.attributeTextView.frame = self.contentView.bounds


// 2 receive config and set to textView
var mooConfig: MOOFoldTextConfig = MOOFoldTextConfig() {
    didSet {
        self.attributeTextView.mooConfig = self.mooConfig
        self.attributeTextView.mooReloadText()
    }
}

// 3.1 define protocol to forward event
public protocol MOOTableViewCellDelegate: AnyObject {
    func mooCellShouldReloadData(_ cell: UITableViewCell)
}
// 3.2
weak var mooDelegate: MOOTableViewCellDelegate?
// 3.3
extension MOOTableViewCell: MOOFoldTextViewDelegate {
    func mooFoldViewShouldUpdateLayout(_ foldTextView: MOOFoldTextView) {
        self.mooDelegate?.mooCellShouldReloadData(self)
    }
}
2.2.2 at View Controller
swift 复制代码
import MOOFoldTextView

// 4.1 init tableView
private lazy var tableView: UITableView = {
    let view = UITableView(frame: .zero, style: .grouped)
    view.register(MOOTableViewCell.self, forCellReuseIdentifier: "MOOTableViewCell")
    view.dataSource = self
    view.delegate = self
    return view
}()
// 4.2 init dataSource with config
private lazy var dataSource: [MOOFoldTextConfig] = {
    let config = MOOFoldTextConfig()
    config.allText =
    """
    Swift is a type-safe language, which means the language helps you to be clear about\
     the types of values your code can work with. If part of your code requires a String,\
    type safety prevents you from passing it an Int by mistake. Likewise, type safety\
    prevents you from accidentally passing an optional String
    """
    config.paragraph.lineSpacing = 10.0
    config.contentWidth = CGRectGetWidth(self.view.bounds)
    return [config]
}()
// 4.3 add to super view
self.view.addSubview(self.tableView)
self.tableView.reloadData()
// 4.4 set frame
self.tableView.frame = CGRect(x: 0.0,
                              y: 100.0,
                              width: CGRectGetWidth(self.view.bounds),
                              height: CGRectGetHeight(self.view.bounds) - 100.0);
                              
// 5.1 Implementation UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MOOTableViewCell",
                                             for: indexPath)
    if let cell = cell as? MOOTableViewCell {
        cell.mooConfig = self.dataSource[indexPath.row]
        cell.mooDelegate = self
    }
    return cell
}
// 5.2 Implementation UITableViewDelegate
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    let config = self.dataSource[indexPath.row]
    return config.currentHeight()
}

// 6 reload data after fold state changed
extension MOOTest2ViewController: MOOTableViewCellDelegate {
    func mooCellShouldReloadData(_ cell: UITableViewCell) {
        self.tableView.reloadData()
    }
}

github

相关推荐
文件夹__iOS10 小时前
SwiftUI 核心选型:class + ObservableObject VS struct + @State
ios·swiftui·swift
SameX15 小时前
独立开发了一款健康记录 App,聊聊几个让我纠结很久的设计决策
ios
报错小能手16 小时前
Swift UI 框架 实战 简易计数器、待办清单 、随机壁纸图库、个人笔记
ui·ios
游戏开发爱好者818 小时前
深入理解iOSTime Profiler:提升iOS应用性能的关键工具
android·ios·小程序·https·uni-app·iphone·webview
for_ever_love__1 天前
UI学习:多界面传值的正向传值(属性传值)和反向传值(代理传值)
学习·ui·ios·objective-c
开心就好20251 天前
全面介绍iOS开发工具:Xcode、AppCode、CocoaPods、Fastlane和Git
后端·ios
懋学的前端攻城狮2 天前
数据持久化与缓存策略:在离线与在线间架起桥梁
ios·swift
~央千澈~2 天前
以cocos3.8.8开发的游戏为例商业实战项目举例cocos打包ios苹果安装包ipa完整详细教程-优雅草卓伊凡
ios
SameX2 天前
iOS 足迹 App 的成就系统,我推倒重做了一次——踩了3个坑之后
ios
SameX2 天前
我做了一个把专注计时变成「声音护照」的 iOS App,聊聊数据可视化和成长系统的设计思路
ios