Skip to content

封装tableViewCell样式不一致的UITableView,告别复杂的DataSource和Delegate。Build static UITableViewCell more conventient

License

Notifications You must be signed in to change notification settings

QDong415/QTableKit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

804f72e · Aug 7, 2022

History

4 Commits
Aug 5, 2022
Aug 5, 2022
Aug 5, 2022
Aug 5, 2022
Aug 5, 2022
Aug 5, 2022
Aug 7, 2022
Aug 5, 2022

Repository files navigation

QTableKit

CI Status Version License Platform

IOS 封装tableViewCell样式不一致的UITableView,告别复杂的DataSource和Delegate

解决痛点,比如要实现下面的商品详情TableView:

QQ20220806-1.jpg

类似登录注册界面的TableView、上面的商品详情的TableView、设置界面的TableView等。 他们的每条Cell的样式都不一致,且都可能hidden。如果用传统的方式处理,会在UITableViewDataSource里写一堆 if else判断本Cell是否应该显示,以让Cell找到对应的indexPath

本库效果图(其实效果图不重要,重要的是代码逻辑):

点击按钮可以获取TextField里的值.gif

Cell的高度可以很方便的控制.gif

本库是基于 TableKit 改造优化

本库使用流程:

先写Cell对应的Model:

//这个TableKitTextFieldCell对应的Model,只能用class,不要用struct;因为struct会在TableKitRow里产生一个无用的深copy
class TableKitTextFieldModel {
       
    var title: String? //左边的Label内容文字
    var value: String? //TextField的输入内容

    //以下是TextField的属性
    var secureTextEntry: Bool = false
    var placeHolder: String?
    var keyboardType: UIKeyboardType = UIKeyboardType.default
    var textAlignment: NSTextAlignment = NSTextAlignment.right
}

再写Cell的代码

//触发cell内部控件的事件的key;用来区分是哪个内部事件
let TKTextFieldEditingChangedKey = "TKTextFieldEditingChangedKey"

//左label,右textField
class TableKitTextFieldCell: UITableViewCell, TableKitCellDataSource {
    
    //声明该cell对应的model数据类型;你可以不用写这句,选择直接把下文中的T换成Model;也能运行但是那样不规范
    typealias T = TableKitTextFieldModel
    
    //主model是在TableKitRow里强引用的,这里只是个副本
    private weak var weakModel: T!
    
    //当用户手动触发cell上的UI控件的各种事件
    //底层原理:把事件通过这个RowActionable回调给TableKitRow;然后TableKitRow收到回调后,再回调给vc的TableRowAction
    private var customRowAction: RowActionable?
    
    //cell上的控件
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var textField: UITextField!
    
    //MARK: TableKitCellDataSource - 默认高度
    //这里的return的高度是第2优先级,如果在ViewController里设置本Cell高度属于第1优先级
    static var defaultHeight: CGFloat? {
        //返回0表示Cell高度为0,不写该方法表示Cell高度为automaticDimension
        return 54
    }
    
    //MARK: TableKitCellDataSource - 绑定model 和 临时存储customRowAction
    //这个回调方法是由系统的cellForRowAtIndexPath触发的,所以要写的内容就跟cellForRowAtIndexPath一样
    func configureData(with tkModel: T ,customRowAction : RowActionable) {
        
        self.weakModel = tkModel
        self.customRowAction = customRowAction
        
        titleLabel.text = tkModel.title
        textField.text = tkModel.value
        textField.placeholder = tkModel.placeHolder
        textField.isSecureTextEntry = tkModel.secureTextEntry
        textField.textAlignment = tkModel.textAlignment
        textField.keyboardType = tkModel.keyboardType
        
        textField.addTarget(self, action: #selector(editingChanged(_:)), for: .editingChanged)
    }
    
    //cell内部控件触发的事件,通过本cell的全局变量customRowAction传给TableKitRow,TableKitRow会再传回给vc
    @objc fileprivate func editingChanged(_ textField:UITextField) {
        // 控件输入监听,监听cell上的UI控件的output值的改变,然后把新值设置回weakModel
        weakModel.value = textField.text;
        customRowAction?.onCustomerAction(customActionKey: TKTextFieldEditingChangedKey, cell: self, path: nil, userInfo: nil)
    }

}

最后是ViewController:

    //管理全部的Cell
    open var tableKitSections = [TableKitSection]()

    //输入账号的Cell
    private var nameTableKitRow: TableKitRow<TableKitTextFieldCell>!

    override func viewDidLoad() {
        let nameTkModel = TableKitTextFieldModel()
        nameTkModel.title = "账号"
        nameTkModel.placeHolder = "请输入账号"
        
        //Cell点击事件
        let cellClickAction = TableRowAction<TableKitTextFieldCell>(.click) { (options :TableRowActionCallback<TableKitTextFieldCell>) in
            options.cell?.textField.becomeFirstResponder()
        }
        
        //cell里的TextField的文本编辑事件
        let textFieldEditAction = TableRowAction<TableKitTextFieldCell>(.custom(TKTextFieldEditingChangedKey)) { (options :TableRowActionCallback<TableKitTextFieldCell>) in
            //options.dataModel 就是 nameTkModel
            print("vc收到账号输入框变化1 = ",options.dataModel.value!)
        }
        
        let section = TableKitSection(headerTitle: "TextFieldCell的HeaderTitle", footerTitle: nil)
        self.nameTableKitRow = TableKitRow<TableKitTextFieldCell>(item: nameTkModel, actions: [cellClickAction, textFieldEditAction])
        section.append(row: self.nameTableKitRow)
        self.tableKitSections.append(section)
    }

安装

先在终端里搜索 pod search QTableKit

如果搜索不到1.0版本,需要更新你电脑的pod仓库,以下是更新步骤:

  • pod repo update —verbose 更新你本地电脑的pod仓库。然后再搜索一次试试看
  • 如果还是搜索不到,执行 rm ~/Library/Caches/CocoaPods/search_index.json 。再搜索就OK了

导入方式

pod 'QTableKit'

Author:DQ

我的其他开源库,给个Star鼓励我写更多好库:

IOS 1:1完美仿微信聊天表情键盘

IOS 自定义UIAlertController,支持弹出约束XibView、弹出ViewController

IOS 封装tableViewCell样式不一致的UITableView,告别复杂的UITableViewDataSource

IOS 仿快手直播界面加载中,顶部的滚动条状LoadingView

IOS 基于个推+华为push的一整套完善的 IM聊天系统

Android 朋友圈列表Feed流的最优化方案,让你的RecyclerView从49帧 -> 57帧

Android 仿大众点评、仿小红书 下拉拖拽关闭Activity

Android 仿快手直播间手画礼物,手绘礼物

Android 直播间聊天消息列表RecyclerView。一秒内收到几百条消息依然不卡顿

Android 仿快手直播界面加载中,顶部的滚动条状LoadingView

Android Kotlin MVVM框架,全世界最优化的分页加载接口、最接地气的封装

Android 基于个推+华为push的一整套完善的android IM聊天系统

About

封装tableViewCell样式不一致的UITableView,告别复杂的DataSource和Delegate。Build static UITableViewCell more conventient

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published