美文网首页
swift版 按钮图片左右上下布局+中间距离

swift版 按钮图片左右上下布局+中间距离

作者: 授之以渔不如授之以鱼 | 来源:发表于2021-03-16 10:21 被阅读0次
    image.png

    意思大家都懂,码来!

    import UIKit
    
    extension UIButton {
        
        /// 按钮布局样式
        public enum ButtonLayoutStyle {
            case none, leftImageRightText, rightImageLeftText, topImageBottomText
        }
        
        fileprivate struct AssociatedKeys {
            static var imageTextSpacing: CGFloat = 0.0
            static var layoutStyle: ButtonLayoutStyle = .none
        }
        
        /// 布局样式
        public var layoutStyle: ButtonLayoutStyle {
            get {
                guard let obj = objc_getAssociatedObject(self, &AssociatedKeys.layoutStyle) as? ButtonLayoutStyle else {
                    return .none
                }
                return obj
            }
            set {
                objc_setAssociatedObject(self, &AssociatedKeys.layoutStyle, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
        
        /// 间隙
        public var imageTextSpacing: CGFloat {
            get {
                guard let obj = objc_getAssociatedObject(self, &AssociatedKeys.imageTextSpacing) as? CGFloat else { return 0 }
                return obj
            }
            set {
                objc_setAssociatedObject(self, &AssociatedKeys.imageTextSpacing, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
        
        /// 计算内部大小(宽高自适应)
        /// 参考:https://github.com/DataDesignSystems/lavoro/blob/02b3090c298c2b4cbea352d9d1adae73eb8022c3/Lavoro/Helpers/UIButton%2BExts.swift
        /// 参考:[关于 UIButton 的 titleEdgeInsets、imageEdgeInsets 及 contentEdgeInsets](https://www.jianshu.com/p/2f0e9150a2a3)
        override open var intrinsicContentSize: CGSize {
            let intrinsicContentSize = super.intrinsicContentSize
            guard self.layoutStyle != .none else {
                return intrinsicContentSize
            }
        
            // 调整边距
            self.adjustInsets()
    
            // 调整宽度
            let spacing = self.imageTextSpacing
            var contentWidth = intrinsicContentSize.width
            var contentHeight = intrinsicContentSize.height
            switch self.layoutStyle {
            case .leftImageRightText:
                contentWidth += spacing
                contentHeight += (titleEdgeInsets.top - titleEdgeInsets.bottom)
                break
            case .rightImageLeftText:
                contentWidth += spacing
                contentHeight += (titleEdgeInsets.top - titleEdgeInsets.bottom)
                break
            case .topImageBottomText:
                contentHeight += spacing
                contentHeight += (titleEdgeInsets.top + abs(imageEdgeInsets.top)) // 追加撑大高度
                break
            default:
                break
            }
    
            // 返回内部大小
            return CGSize(width: contentWidth, height: contentHeight)
        }
        
        /// 调整边距 参考:https://github.com/Jyhwenchai/UIButton
        func adjustInsets() {
            
            // Use predefined font, otherwise use the default
            let text = titleLabel?.text ?? ""
            let font: UIFont = titleLabel?.font ?? UIFont()
            let textSize: CGSize = text.size(withAttributes: [NSAttributedString.Key.font: font])
            let imageSize: CGSize = self.imageRect(forContentRect: frame).size
            
            let spacing = self.imageTextSpacing
            let offset = spacing / 2.0
    
            switch self.layoutStyle {
            case .leftImageRightText: // ---|--- 文字右移,图片左移
                self.titleEdgeInsets = UIEdgeInsets(top: 0, left: offset, bottom: 0, right: -offset)
                self.imageEdgeInsets = UIEdgeInsets(top: 0, left: -offset, bottom: 0, right: offset)
                break
            case .rightImageLeftText: // ---|--- 文字左移,图片右移
                let titleHOffset = imageSize.width
                let imageHOffset = textSize.width
    
                // 1) 左右布局
                let titleInsets = UIEdgeInsets(top: 0, left: -titleHOffset, bottom: 0, right: titleHOffset)
                let imageInsets = UIEdgeInsets(top: 0, left: imageHOffset, bottom: 0, right: -imageHOffset)
                // 2) 追加间隔
                self.titleEdgeInsets = UIEdgeInsets(top: 0, left: titleInsets.left - offset, bottom: 0, right: titleInsets.right + offset)
                self.imageEdgeInsets = UIEdgeInsets(top: 0, left: imageInsets.left + offset, bottom: 0, right: imageInsets.right - offset)
                break
            case .topImageBottomText: // 文字下移,图片上移
                let titleHOffset = imageSize.width / 2.0
                let imageHOffset = textSize.width / 2.0
                let titleVOffset = imageSize.height / 2.0
                let imageVOffset = textSize.height / 2.0
                // 1) 上下布局
                let titleInsets = UIEdgeInsets(top: titleVOffset, left: -titleHOffset, bottom: -titleVOffset, right: titleHOffset)
                let imageInsets = UIEdgeInsets(top: -imageVOffset, left: imageHOffset, bottom: imageVOffset, right: -imageHOffset)
                // 2) 追加间隔
                self.titleEdgeInsets = UIEdgeInsets(top: titleInsets.top + offset, left: titleInsets.left, bottom: titleInsets.bottom - offset, right: titleInsets.right)
                self.imageEdgeInsets = UIEdgeInsets(top: imageInsets.top - offset, left: imageInsets.left, bottom: imageInsets.bottom + offset, right: imageInsets.right)
                break
            default:
                break
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:swift版 按钮图片左右上下布局+中间距离

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