底部输入框组件的一次实践

在这里插入图片描述
底部输入框:常用于文章的评论,分享,点赞。造一个通用的组件能帮助开发使用。
入坑点:
一开始根据设计稿8种类型设置了枚举,通过关联值来传递参数,在viewdidload中switch type来动态添加子视图,根据初始化方法中是否带文本来添加按钮旁的文本,整个布局视图代码臃肿、繁琐重复,代码质量是十分差可重用性也差。
改善思路:
同事推荐官方navigationItem.leftBarButtonItems的思路来写,根据传入的item数组来动态创建。限制左右item的数量,根据item一次创建视图然后更新布局。

//
//  BottomInputBoxView.swift
//  QDReaderHelper
//
//  Created by wuxueqian on 2020/7/29.
import UIKit
import SnapKit

class BottomInputBoxView: UIView {
    
    
    
    //MARK: - 公有属性
    
    public var leftButtonItems: [BottomButtonItem]? {
    
    
        didSet {
    
    
            setupLeftItems()
            updateCommentTriggerViewFrame()
        }
    }
    
    public var rightButtonItems: [BottomButtonItem]? {
    
    
        didSet {
    
    
            setupRightItems()
            updateCommentTriggerViewFrame()
        }
    }
    
    public var commentTriggerView = CommentTriggerView()
    
    // MARK: - 私有属性
    
    private var leftOffset = 16 // 左偏移
    private var rightOffset = -16
    private let leftItemsMaxNumber = 1 // 左边Items支持最大数量
    private let rightItemsMaxNumber = 3 // 右边Items支持最大数量
    private let itemSpacing = 16 // item间距
    
    // MARK: - 公有方法
    
    /// 底部输入框视图初始化方法
    /// - Parameters:
    ///   - placeHolder: 占位文本
    ///   - triggerBlock: 点击回调
    ///   - leftButtonItems: 左边Items
    ///   - rightButtonItems: 右边Items
    public init(placeHolder: String?, triggerBlock: (() -> Void)?, leftButtonItems: [BottomButtonItem]? = nil, rightButtonItems: [BottomButtonItem]? = nil) {
    
    
        super.init(frame: .zero)
        setupCommentTriggerView(placeHolder: placeHolder, triggerBlock: triggerBlock)
        self.leftButtonItems = leftButtonItems
        self.rightButtonItems = rightButtonItems
        if leftButtonItems != nil {
    
    
            setupLeftItems()
        }
        if rightButtonItems != nil {
    
    
            setupRightItems()
        }
        updateCommentTriggerViewFrame()
    }
    
    required init?(coder: NSCoder) {
    
    
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 私有方法
    
    /// 配置评论视图
    /// - Parameters:
    ///   - placeHolder: 占位文本
    ///   - triggerBlock: 点击回调
    private func setupCommentTriggerView(placeHolder: String?, triggerBlock: (() -> Void)?) {
    
    
        commentTriggerView.placeHolderText = placeHolder
        commentTriggerView.triggerBlock = triggerBlock
        addSubview(commentTriggerView)
        commentTriggerView.snp.makeConstraints {
    
     (make) in
            make.left.equalToSuperview().offset(leftOffset)
            make.right.equalToSuperview().offset(rightOffset)
            make.top.equalToSuperview().offset(8)
            make.bottom.equalToSuperview().offset(-8)
        }
    }
    
    /// 配置左边Items
    private func setupLeftItems() {
    
    
        if let leftItems = leftButtonItems?.prefix(leftItemsMaxNumber) {
    
    
            for item in leftItems {
    
    
                addSubview(item)
            }
            for item in leftItems {
    
    
                let itemWidth = item.hasText ? 50 : 24
                item.snp.makeConstraints {
    
     (make) in
                    make.width.equalTo(itemWidth)
                    make.height.equalTo(24)
                    make.left.equalToSuperview().offset(leftOffset)
                    make.top.equalToSuperview().offset(14)
                }
                leftOffset = leftOffset + itemWidth + itemSpacing
            }
        }
    }
    
    /// 配置右边Items
    private func setupRightItems() {
    
    
        if let rightItems = rightButtonItems?.prefix(rightItemsMaxNumber) {
    
    
            for item in rightItems {
    
    
                addSubview(item)
            }
            for item in rightItems.reversed() {
    
    
                let itemWidth = item.hasText ? 50 : 24
                item.snp.makeConstraints {
    
     (make) in
                    make.width.equalTo(itemWidth)
                    make.height.equalTo(20)
                    make.right.equalToSuperview().offset(rightOffset)
                    make.top.equalToSuperview().offset(14)
                }
                rightOffset = rightOffset - itemWidth - itemSpacing
            }
        }
    }
    
    /// 更新评论视图
    private func updateCommentTriggerViewFrame() {
    
    
        commentTriggerView.snp.updateConstraints {
    
     (make) in
            make.left.equalToSuperview().offset(leftOffset)
            make.right.equalToSuperview().offset(rightOffset)
        }
    }
}

//
//  BottomButtonItem.swift
//  QDReaderHelper
//
//  Created by wuxueqian on 2020/8/24.
//  Copyright © 2020 洋葱. All rights reserved.
//

import UIKit

/*
 底部输入框 ButtonItem
 类型:带文本 / 不带文本
 大小:50*24 / 24*24
 */
class BottomButtonItem: UIView {
    
    
    
    // MARK: - 公有属性
    
    public var hasText: Bool = false // 是否附带文本
    
    // MARK: - 私有属性
    
    private var button: UIButton = {
    
    
        let button = UIButton()
        return button
    }()
    
    private var label: UILabel = {
    
    
        let label = UILabel()
        label.font = UIFont.qdFont_Caption()
        label.textColor = UIColor.qdColor_surface_gray_900()
        return label
    }()
    
    // MARK: - 公有方法
    
    /// 底部输入框ButtomItem初始化方法
    /// - Parameters:
    ///   - title: 右侧文本
    ///   - image: 按钮图片
    ///   - target: 目标
    ///   - action: 动作
    public init(title: String?, image: UIImage?, target: Any?, action: Selector?) {
    
    
        super.init(frame: .zero)
        setupButton(image: image, target: target, action: action)
        setupLabel(title: title)
    }
    
    required init?(coder: NSCoder) {
    
    
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 私有方法
    
    /// 配置按钮
    private func setupButton(image: UIImage?, target: Any?, action: Selector?) {
    
    
        button.setImage(image, for: .normal)
        if action != nil {
    
    
            button.addTarget(target, action: action!, for: .touchUpInside)
        }
        addSubview(button)
        button.snp.makeConstraints {
    
     (make) in
            make.width.height.equalTo(24)
        }
    }
    
    /// 配置右侧文本
    private func setupLabel(title: String?) {
    
    
        if title != nil {
    
    
            hasText = true
            label.text = title!
            addSubview(label)
            label.snp.makeConstraints {
    
     (make) in
                make.left.equalTo(self.button.snp.right).offset(4)
                make.height.equalTo(24)
                make.right.equalToSuperview()
            }
        }
    }
}

//
//  CommentTriggerView.swift
//  QDReaderHelper
//
//  Created by wuxueqian on 2020/7/29.
//  Copyright © 2020 洋葱. All rights reserved.
//

import UIKit
import SnapKit

/*
 CommentTriggerView 评论触发器视图
 */

class CommentTriggerView: UIView {
    
    
    
    // MARK: - 公有属性
    
    public var triggerBlock: (() -> Void)? {
    
    
        didSet {
    
    
            self.triggerButton.addTarget(self, action: #selector(clickButton), for: .touchUpInside)
        }
    }
    
    public var placeHolderText: String? {
    
    
        didSet {
    
    
            if placeHolderText != nil {
    
    
                self.placeHolderLabel.text = placeHolderText
            }
        }
    }

    // MARK: - 私有属性

    private lazy var placeHolderLabel: UILabel = {
    
    
        let label = UILabel()
        label.textColor = UIColor.qdColor_surface_gray_300()
        label.font = UIFont.qdFont_Body2()
        label.text = "有想法快点写下来吧..."
        return label
    }()
    
    private lazy var triggerButton: UIButton = {
    
    
        let button = UIButton(type: .custom)
        button.backgroundColor = .clear
        return button
    }()
    
    private lazy var backView: UIView = {
    
    
        let view = UIView()
        view.layer.masksToBounds = true
        view.layer.cornerRadius = 18
        view.backgroundColor = UIColor.qdColor_surface_gray_50()
        return view
    }()
    
    
    // MARK: - 公有方法
    
    public init(placeHolderText: String?, leftBtns: [BottomButtonItem]? = nil, triggerBlock: (() -> Void)?) {
    
    
        super.init(frame: .zero)
        if let text = placeHolderText {
    
    
            self.placeHolderText = text
        }
        if let block = triggerBlock {
    
    
            self.triggerBlock = block
        }
        setupView()
    }
    
    override init(frame: CGRect) {
    
    
        super.init(frame: frame)
        setupView()
    }
    
    required init?(coder: NSCoder) {
    
    
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 私有方法
    
    @objc private func clickButton() {
    
    
        triggerBlock?()
    }
    
    private func setupView() {
    
    
        addSubview(backView)
        addSubview(placeHolderLabel)
        addSubview(triggerButton)
        self.backView.snp.makeConstraints {
    
     (make) in
            make.left.right.top.bottom.equalToSuperview()
        }
        self.placeHolderLabel.snp.makeConstraints {
    
     (make) in
            make.left.equalToSuperview().offset(16)
            make.right.equalToSuperview().offset(-16)
            make.top.equalToSuperview().offset(6)
            make.bottom.equalToSuperview().offset(-6)
        }
        self.triggerButton.snp.makeConstraints {
    
     (make) in
            make.edges.equalToSuperview()
        }
    }

}

猜你喜欢

转载自blog.csdn.net/WxqHUT/article/details/108202843