美文网首页
简单封装系统LayoutConstraint,实现类似Mason

简单封装系统LayoutConstraint,实现类似Mason

作者: Grabin | 来源:发表于2018-04-12 22:33 被阅读41次

    GitHub上的代码👉,后续有时间会有更新。>>>GRLayout demo

    image.png
    • 使用

    import UIKit
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            let testView = UIView()
            testView.backgroundColor = .yellow
            view.addSubview(testView)
            testView.gr_top.equal(view.gr_top).offset(100.0)
            testView.gr_left.equal(view.gr_left).offset(10.0)
            testView.gr_right.equal(view.gr_right).offset(-10.0)
            testView.gr_bottom.equal(view.gr_bottom).offset(-100)
    //        testView.gr_height.greaterThanOrEqual(200.0)
        }
    }
    
    
    
    • 设计

    第一反应想到的是给UIView做一个extension,让它及其子类都带有特定都属性,可以调用方法去设置,修改约束。
    所以这里设计了几个属性,用于约束设置。

    • gr_top
    • gr_bottom
    • gr_left
    • gr_right
    • gr_height
    • gr_width
    在UIView+Extension.swift 文件中,代码如下:
    import UIKit
    
    extension UIView {
        
        var gr_top: GRLayoutY {
            get {
                translatesAutoresizingMaskIntoConstraints = false
                return GRLayoutY.create(anchor: topAnchor)
            }
        }
    
        var gr_bottom: GRLayoutY {
            get {
                translatesAutoresizingMaskIntoConstraints = false
                return GRLayoutY.create(anchor: bottomAnchor)
            }
        }
    
        var gr_left: GRLayoutX {
            get {
                translatesAutoresizingMaskIntoConstraints = false
                return GRLayoutX.create(anchor: leftAnchor)
            }
        }
    
        var gr_right: GRLayoutX {
            get {
                translatesAutoresizingMaskIntoConstraints = false
                return GRLayoutX.create(anchor: rightAnchor)
            }
        }
    
        var gr_height: GRLayoutDimension {
            get {
                translatesAutoresizingMaskIntoConstraints = false
                return GRLayoutDimension.create(anchor: heightAnchor)
            }
        }
    
        var gr_width: GRLayoutDimension {
            get {
                translatesAutoresizingMaskIntoConstraints = false
                return GRLayoutDimension.create(anchor: widthAnchor)
            }
        }
    }
    
    
    
    • 添加方法实现,实现像Masonry链式编程的约束方法。(如果不明白什么是链式编程,可以看这里)

    class GRLayoutY: NSObject {
        open var constant: CGFloat = 0.0 {
            didSet {
                curLayoutConstraint.constant = constant
            }
        }
        
        open var priority: Int = 1000 {
            didSet {
                curLayoutConstraint.priority = UILayoutPriority(rawValue: Float(priority))
            }
        }
        
        private var curLayoutConstraint = NSLayoutConstraint()
        private var curAnchor = NSLayoutYAxisAnchor()
        
        open class func create(anchor: NSLayoutYAxisAnchor) -> GRLayoutY {
            let grabin = GRLayoutY()
            grabin.curAnchor = anchor
            return grabin
        }
        
        @discardableResult open func equal(_ other: GRLayoutY) -> GRLayoutY {
            curLayoutConstraint = curAnchor.constraint(equalTo: other.curAnchor)
            curLayoutConstraint.isActive = true
            return self
        }
        
        @discardableResult open func offset(_ offSet: CGFloat) -> GRLayoutY {
            curLayoutConstraint.constant = offSet
            return self
        }
    }
    
    class GRLayoutX: NSObject {
        open var constant: CGFloat = 0.0 {
            didSet {
                curLayoutConstraint.constant = constant
            }
        }
        open var priority: Int = 1000 {
            didSet {
                curLayoutConstraint.priority = UILayoutPriority(rawValue: Float(priority))
            }
        }
        private var curLayoutConstraint = NSLayoutConstraint()
        private var curAnchor = NSLayoutXAxisAnchor()
        
        open class func create(anchor: NSLayoutXAxisAnchor) -> GRLayoutX {
            let grabin = GRLayoutX()
            grabin.curAnchor = anchor
            return grabin
        }
        
        @discardableResult open func equal(_ other: GRLayoutX) -> GRLayoutX {
            curLayoutConstraint = curAnchor.constraint(equalTo: other.curAnchor)
            curLayoutConstraint.isActive = true
            return self
        }
        
        @discardableResult open func offset(_ offSet: CGFloat) -> GRLayoutX {
            curLayoutConstraint.constant = offSet
            return self
        }
    }
    
    class GRLayoutDimension: NSObject {
        open var constant: CGFloat = 0.0 {
            didSet {
                curLayoutConstraint.constant = constant
            }
        }
        open var priority: Int = 1000 {
            didSet {
                curLayoutConstraint.priority = UILayoutPriority(rawValue: Float(priority))
            }
        }
        private var curLayoutConstraint = NSLayoutConstraint()
        private var curAnchor = NSLayoutDimension()
        
        open class func create(anchor: NSLayoutDimension) -> GRLayoutDimension {
            let grabin = GRLayoutDimension()
            grabin.curAnchor = anchor
            return grabin
        }
        
        @discardableResult open func equal(_ other: GRLayoutDimension, multiplier: CGFloat = 1) -> GRLayoutDimension {
            curLayoutConstraint = curAnchor.constraint(equalTo: other.curAnchor, multiplier: multiplier)
            curLayoutConstraint.isActive = true
            return self
        }
        
        @discardableResult open func equal(_ equalToConstant: CGFloat) -> GRLayoutDimension {
            curLayoutConstraint = curAnchor.constraint(equalToConstant: equalToConstant)
            curLayoutConstraint.isActive = true
            return self
        }
        
        @discardableResult open func greaterThanOrEqual(_ toConstant: CGFloat) -> GRLayoutDimension {
            curLayoutConstraint = curAnchor.constraint(greaterThanOrEqualToConstant: toConstant)
            curLayoutConstraint.isActive = true
            return self
        }
        
        @discardableResult open func lessThanOrEqual(_ toConstant: CGFloat) -> GRLayoutDimension {
            curLayoutConstraint = curAnchor.constraint(lessThanOrEqualToConstant: toConstant)
            curLayoutConstraint.isActive = true
            return self
        }
        
        @discardableResult open func offset(_ offSet: CGFloat) -> GRLayoutDimension {
            curLayoutConstraint.constant = offSet
            return self
        }
    }
    
    • Tips

    让Xcode不报返回值使用警告,可以在带返回值的方法前加 @discardableResult

    相关文章

      网友评论

          本文标题:简单封装系统LayoutConstraint,实现类似Mason

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