美文网首页
Swift | BWEmptyKit 列表占位框架

Swift | BWEmptyKit 列表占位框架

作者: 清無 | 来源:发表于2022-03-02 11:00 被阅读0次

    简介

    本框架是基于BWListKit库,进行扩展开发的列表视图占位工具类库,支持空数据、网络失败、请求失败、自定义类型等,方便使用。
    建议先了解BWListKit这个框架,再来了解和使用BWEmptyKit

    BWListKit

    https://www.jianshu.com/p/77d4e5402e3a

    演示

    竖屏 转屏

    用法

    默认类型
    • 自定义快捷扩展
      extension Empty.SenarioSet
    extension Empty.SenarioSet {
        static func appNoData(_ handler: @escaping ()->Void) -> Empty.SenarioSet {
            return .init(senario: .noData, data: .init(styling: { emptyView in
                emptyView.label?.font = UIFont.system16
                emptyView.label?.textColor = .red
            }, image: UIImage(named: "empty_no-data"), tips: "当前没有任何数据哦~", action: .init(icon: UIImage(named: "ic_book"), title: "去书架看看", handler: handler)))
        }
        static let appNetworkError = Empty.SenarioSet(senario: .networkError, data: .init(styling: { emptyView in
            emptyView.button?.titleLabel?.font = UIFont.system16
            emptyView.button?.tintColor = .red
        }, image: UIImage(named: "empty_network-error"), tips: "吼吼,貌似你的网络有问题哦~", action: .init(icon: UIImage(named: "ic_refresh"), title: "去检查网络", handler: {
            Dialog.show(title: "去检查网络", maskViewCancellable: true)
        })))
        static func appRequestFailed(_ handler: @escaping ()->Void) -> Empty.SenarioSet {
            return .init(senario: .requestFailed, data: .init(image: UIImage(named: "empty_request-failed"), tips: "十分抱歉,数据请求失败啦~", action: .init(icon: UIImage(named: "ic_ball"), title: "重新请求", handler: handler)))
        }
    }
    
    • 绑定
    class ViewController: TableViewController {
        override func didLoad() {
            super.didLoad()
            
    /// 绑定自定义empty到listAdapter(BWListKit)
            Empty.binds(
            [
                .appNoData {
                    HUD.toast("去书架看看", position: .top)
                },
                .appNetworkError,
                .appRequestFailed {
                    HUD.toast("重新请求", position: .middle)
                },
            ], for: listAdapter)
        }
    }
    
    • 显示
    var currentEmpty: Empty.Senario?
    /// IBAction
        @IBAction func changeEmpty(_ sender: UISegmentedControl) {
            let idx = sender.selectedSegmentIndex
            switch idx {
            case 0:
                currentEmpty = .noData
            case 1:
                currentEmpty = .networkError
            case 2:
                currentEmpty = .requestFailed
            default: break
            }
    /// API用法
            Empty.show(currentEmpty!, for: listAdapter)
        }
    
    自定义类型
    • 自定义快捷用法
      CustomEmptyType
    enum CustomEmptyType: String {
        case noOrders = "empty_no-orders"
        case noGoods = "empty_no-goods"
        case noUpdates = "empty_no-updates"
        
        var icon: UIImage? {
            return UIImage(named: rawValue)
        }
        var tips: String? {
            switch self {
            case .noOrders: return "当前没有任何订单哦,快去商城看看吧~"
            case .noGoods: return "该分类下暂时没有商品哦,换个分类试试吧~"
            case .noUpdates: return "当前文章还未发布呢,到别处逛逛吧~"
            }
        }
        var actionTitle: String? {
            switch self {
            case .noOrders: return "去商城"
            case .noGoods: return "换个分类"
            case .noUpdates: return "去贴吧"
            }
        }
        var actionIcon: UIImage? {
            switch self {
            case .noOrders: return .init(named: "ic_discount")
            case .noGoods: return .init(named: "ic_filter")
            case .noUpdates: return .init(named: "ic_pie-chart")
            }
        }
        
        func action(_ handler: (()->Void)? = nil) -> Empty.Data.Action {
            return .init(icon: actionIcon, title: actionTitle, handler: handler)
        }
    }
    

    extension Empty.SenarioSet

    extension Empty.SenarioSet {
        static func appCustom(_ type: CustomEmptyType, handler: (()->Void)? = nil) -> Empty.SenarioSet {
            return .init(senario: .custom(type), data: .init(styling: {
                $0.stackView?.spacing = 40
                $0.label?.textAlignment = .center
                $0.button?.imageEdgeInsets = .with(left: -2)
                $0.button?.titleEdgeInsets = .with(right: -2)
                $0.button?.contentEdgeInsets = .with(horizontal: 12, vertical: 4)
                $0.button?.layer.borderWidth = 0.5
                $0.button?.layer.borderColor = UIColor.lightGray.cgColor
                $0.button?.tintColor = UIColor.systemRed
                $0.button?.layer.cornerRadius = $0.button!.bounds.height/2
            }, image: type.icon, tips: type.tips, action: type.action(handler)))
        }
    }
    
    • 绑定
    class ViewController: TableViewController {
        override func didLoad() {
            super.didLoad()
            
            Empty.binds(
            [
                .appCustom(.noOrders, handler: {
                    Dialog.show(title: CustomEmptyType.noOrders.actionTitle, maskViewCancellable: true)
                }),
                .appCustom(.noGoods, handler: {
                    Dialog.show(title: CustomEmptyType.noGoods.actionTitle, maskViewCancellable: true)
                }),
                .appCustom(.noUpdates, handler: {
                    Dialog.show(title: CustomEmptyType.noUpdates.actionTitle, maskViewCancellable: true)
                }),
            ], for: listAdapter)
        }
    }
    
    • 显示
    @IBAction func changeCustomEmpty(_ sender: UISegmentedControl) {
            let idx = sender.selectedSegmentIndex
            switch idx {
            case 0:
                currentEmpty = .custom(CustomEmptyType.noGoods)
            case 1:
                currentEmpty = .custom(CustomEmptyType.noOrders)
            case 2:
                currentEmpty = .custom(CustomEmptyType.noUpdates)
            default: break
            }
    /// API
            Empty.show(currentEmpty!, for: listAdapter)
        }
    

    布局适配

    屏幕旋转后,重新布局emptyView

    /// 此方法为`BWUIKit`里`ViewController`的快捷方法,具体实现可参照`BWUIKit`库
    override func layoutDidChange() {
            super.layoutDidChange()
            
            if let _ = Empty.showing(for: listAdapter) {
                Empty.reload(for: listAdapter)
            }
        }
    

    其他API

    // 当前显示
    public static func showing(for listAdapter: BWListAdapter) -> Senario?{}
    
    // 移除
    public static func remove(_ senario: Senario, for listAdapter: BWListAdapter){}
    
    // 更新数据
    public static func update(_ senario: Senario, data: Empty.Data, for listAdapter: BWListAdapter){}
    
    // 刷新
    public static func reload(_ senario: Senario, for listAdapter: BWListAdapter){}
    
    // 显示自定义`view`
    public static func showCustom(_ emptyView: UIView, on view: UIView){}
    

    源码

    https://gitee.com/flytoo/BWEmptyKit

    Github太慢了,暂时放在gitee上,还在持续更新改进中,欢迎留言指正。

    相关文章

      网友评论

          本文标题:Swift | BWEmptyKit 列表占位框架

          本文链接:https://www.haomeiwen.com/subject/vcysrrtx.html