美文网首页
冰清玉洁的IOS代码---精简SnapKit

冰清玉洁的IOS代码---精简SnapKit

作者: 747a945a4501 | 来源:发表于2018-06-13 18:01 被阅读105次

    前言

    由于新工作只做IOS开发,所以技术的中心开始像Swift方向转变。顺便也把以前封装的老库在拿过来改改弄弄。我开发风格一直追求的是极简风,所以减少代码量一直是我这几年干的事情。最近把我减少代码的一些东西分享下。
    今天分享的是Snapkit,IOS上dsl风格的优雅的实现约束布局,用了好几个形容词。

    SnapKit

    首先看它的官方介绍如下:


    image.png

    本身的框架就是为了实现布局代码的减少,号称用代码可以很轻松的完成 布局的构建。当然事实上也是这样的。

    然后DSL风格是最近框架的流行风,实现得益于闭包语法糖的强大。

    //创建约束
    view.snp.makeConstraints{
                $0.top.equalToSuperview().offset(100)
                $0.left.equalToSuperview()
                $0.right.equalToSuperview()
                $0.height.equalTo(300)
            }
    //修改
    view.snp.removeConstraints{
                $0.top.equalToSuperview().offset(100)
                .....
            }
    //更新
    view.snp.updateConstraints{
                $0.top.equalToSuperview().offset(100)
                .....
            }
    

    用法是非常简单,基本上用一次都会。
    那么无论从优雅度 还是 简单度都是非常不错,那为什么还要封装它?

    因为代码行数太多了, 一个控件的行数 = 约束(3-6行) + view的构建和设置 (3-5行) + DSL的大括号(2行) + addSubView (1行) = 一个控件要花掉至少10行的代码。
    如果有10个控件 单单布局就要花掉100代码,好恐怖。

    简化

    如何简化,就是找代码的共同点 然后去掉。
    当然语法糖的无法无天,让我们的简化思想变得胆大包天。和以前封装一样,我首先问自己想要实现什么方式?
    下面是我无法无天的思想

    //方法一  运算符 + 类目分离 (放弃 代码嫌多)
     10  <<< view.h >> (otherView,10)
     (otherView,15) <<< view.v >> (otherView,10)
    view.widht = 10
    
     10  <<< view.h >> (otherView,10)
     (otherView,15) <<< view.v >> (otherView,10)
    view.widht = 10
    
    //方法二  运算符 + 链式调用 (放弃 运算符多记不住  且没有联想功能  组合的优先级设置有难度   )
    self.view ++ leftTestView.make <<< -10 >>> 10 ^~ (centerView,10)
    self.view ++ topTestView.make ~^ -10 >>< (centerView,10)
    self.view ++ midTestView.make ~- 0 <<> (centerView,10)
    
    //方法三 纯链式
    self ++ centerView.make.width(100).height(60).centerParent()
    self ++ leftTestView.make.left(10).right(10).topToBottom(20,centerView)
    self ++ topTestView.make.bottomToTop(-10).rightToLeft(10, centerView)
    

    其实封装看方法名字 就能知道意思,下面讲一些改进的地方,然后贴出源码

    增加等边 横竖父空间边距 方便父控件包裹内容

      view.equilateral(50).horizontalToParent(10,13)
      view.equilateralToParent(0.5,0.4).verticalToParent(10,13)
    

    对同一个控件约束缓存

     //如果都是对centerView约束  那么前面可以不指定
      self ++ leftTestView.make.left(10).right(10).topToBottom(20,centerView)
    

    安全!!! 这样更新不会报错 <Snp的updateConstraints的时候 如果没有设置这个约束 会报错>

     //   这样更新不会报错
     leftTestView.makeCache.left(10).right(10).topToBottom(20,centerView).update()
    

    支持多下标更换 约束 note: 索引不会越界 随心所欲

    //如果我想改其中某个约束 不需要重新remake  
    leftCons[2,4,6] = { 
       $0.topToBottom(20,centerView) 
       $0.right(12,centerView)
    }
    

    拒绝内存泄露

    好处

    代码少多少? 原来的10行代码 = 现在只要1行,你觉得少多少呢?
    配合后面即将分享的 实现Flexbox 支持流线布局 + 极简的控件初始化会让代码量上一个层次。

    举个例子<实现如下如的布局>:


    image.png
      //不需要指定父容器尺寸  自适应
      self ++ nameView.leftToParent(16).centerYToParent()
      self ++ rightArrowView.rightToParent(-16).centerYToParent()
      self ++ faceView.verticalToParent(10,-10).rightToLeft(10,rightArrowView)
    

    源码

    import Foundation
    import SnapKit
    
    //##############################################################
    //# 对齐方式  左<< 右>> 水平基线 |   上^  下~  垂直基线 -
    //# 目标  !
    //# 左约束 <<  <|  <>
    //# 右约束 ><  >|  >>
    //# 上约束 ^^  ^-  ^_
    //# 下约束 _^  _- __
    //# 水平约束 |=  |<  |>
    //# 垂直约束 --  -^  -~
    //# #居中  >><<
    //# 边距相同 <<>>
    //# 宽高度等于 |== -==
    //##############################################################
    
    infix operator ++ : ViewSetupPrecedence
    //左边约束
    infix operator <<< : LeftPrecedence
    
    infix operator <<| : LeftPrecedence
    
    infix operator <<> : LeftPrecedence
    
    //右边约束
    
    infix operator >>< : LeftPrecedence
    
    infix operator >>| : LeftPrecedence
    
    infix operator >>> : LeftPrecedence
    
    //顶部约束
    infix operator ^^ : LeftPrecedence
    
    infix operator ^- : LeftPrecedence
    
    infix operator ^~ : LeftPrecedence
    
    //底部约束
    infix operator ~^ : LeftPrecedence
    
    infix operator ~- : LeftPrecedence
    
    infix operator ~~ : LeftPrecedence
    
    //水平约束
    infix operator |= : LeftPrecedence
    
    infix operator |< : LeftPrecedence
    
    infix operator |> : LeftPrecedence
    
    //垂直约束
    infix operator -- : LeftPrecedence
    
    infix operator -^ : LeftPrecedence
    
    infix operator -~ : LeftPrecedence
    
    //居中
    infix operator >><< : LeftPrecedence
    infix operator <<>> : LeftPrecedence
    
    prefix operator =>
    
    precedencegroup ViewSetupPrecedence {
        associativity: left
        higherThan: AssignmentPrecedence
        lowerThan: BitwiseShiftPrecedence
    }
    
    precedencegroup LeftPrecedence {
        associativity: left
        higherThan: ViewSetupPrecedence
        lowerThan: BitwiseShiftPrecedence
    }
    
    enum SimplifyAlignment {
        case begin
        case middle
        case end
    }
    
    extension UIView {
        
        var make : WrapConstraintMaker { return WrapConstraintMaker(self) }
        
        var makeCache : WrapConstraintMaker { return WrapConstraintMaker(self,true) }
        
        @discardableResult
        static func ++ (left: UIView, right: WrapConstraintMaker) -> WrapConstraintMaker{
            guard let sView = right.mineView else { return right }
            left.addSubview(sView)
            sView.snp.makeConstraints { constraint in
                right.buildMakes(constraint)
            }
            return right
        }
        
    }
    
    extension UIViewController {
        
        @discardableResult
        static func ++ (left: UIViewController, right: WrapConstraintMaker) -> WrapConstraintMaker {
            return left.view ++ right
        }
        
    }
    
    
    class WrapConstraintMaker {
        //不在使用 weak  防止变量提前释放  改为手动释放 fileprivate
        var mineView : UIView? = nil
        //当缓存的时候
        weak var cacheView : UIView? = nil
        var isCache : Bool = false
        private var allMakers = [( (ConstraintMaker)-> Void )]()
        //暂存的约束 用于
        private var stashMakers:[( (ConstraintMaker)-> Void )]? = nil
        
        private var lastMakers = [( (ConstraintMaker,UIView)-> Void )]()
        
        init(_ view:UIView,_ isCache : Bool = false){
            self.mineView = view
            self.isCache = isCache
            if isCache { self.cacheView = view }
        }
        
        private func hRelateTarget(_ host:UIView, _ alig : SimplifyAlignment) -> ConstraintRelatableTarget {
            var target:ConstraintRelatableTarget?
            switch alig {
            case .end:
                target = host.snp.right
            case .middle:
                target = host.snp.centerX
            default:
                target = host.snp.left
            }
            return target!
        }
        
        private func vRelateTarget(_ host:UIView, _ alig : SimplifyAlignment) -> ConstraintRelatableTarget {
            var target:ConstraintRelatableTarget?
            switch alig {
            case .end:
                target = host.snp.bottom
            case .middle:
                target = host.snp.centerY
            default:
                target = host.snp.top
            }
            return target!
        }
        
        private func lastProcess(_ curView:UIView ){
            lastMakers.forEach{ process in
                allMakers.append{ m in
                    process(m,curView)
                }
            }
            lastMakers.removeAll()
        }
        
        private func addMakeProcess(_ ardView:UIView?, _ process : @escaping (ConstraintMaker,UIView)-> Void ) -> WrapConstraintMaker{
            if let view = ardView {
                lastProcess(view)
                if let _ = stashMakers {
                    stashMakers?.append{ process($0,view) }
                } else {
                    allMakers.append{ process($0,view) }
                }
            } else {
                lastMakers.append(process)
            }
            return self
        }
        
        fileprivate func buildMakes(_ cons: ConstraintMaker){
            allMakers.forEach{ $0(cons) }
            if !isCache { allMakers.removeAll() }
            mineView = nil
        }
        
        private func addMakeProcessImmediately(_ process : @escaping (ConstraintMaker)-> Void ) -> WrapConstraintMaker{
            if let _ = stashMakers {
                stashMakers?.append(process)
            } else {
                allMakers.append(process)
            }
            return self
        }
        
        //MARK: -------------  左约束  ------------------
        @discardableResult
        private func leftConstraint( _ ardView:UIView?,_ offset: CGFloat,_ alignment: SimplifyAlignment ) -> WrapConstraintMaker{
            return addMakeProcess(ardView){ m,v in m.left.equalTo( self.hRelateTarget(v,alignment) ).offset(offset) }
        }
        
        @discardableResult
        func left( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return leftConstraint(ardView,offset,SimplifyAlignment.begin)
        }
        
        @discardableResult
        func leftToParent( _ offset: CGFloat = 0 ) -> WrapConstraintMaker {
            return addMakeProcessImmediately{ $0.left.equalToSuperview().offset(offset) }
        }
        
        @discardableResult
        static func <<< (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.leftConstraint( right.0,right.1,SimplifyAlignment.begin )
        }
        
        @discardableResult
        static func <<< (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left <<< (nil ,right) }
        
        @discardableResult
        func leftToCenter( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return leftConstraint(ardView,offset,SimplifyAlignment.middle)
        }
        
        @discardableResult
        static func <<| (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.leftConstraint( right.0,right.1,SimplifyAlignment.middle )
        }
        
        @discardableResult
        static func <<| (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left <<| (nil ,right) }
        
        @discardableResult
        func leftToRight( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return leftConstraint(ardView,offset,SimplifyAlignment.end)
        }
        
        @discardableResult
        static func <<> (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.leftConstraint( right.0,right.1,SimplifyAlignment.end )
        }
        
        @discardableResult
        static func <<> (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left <<> (nil ,right) }
        
        //MARK: -------------  右对齐 ------------------
        @discardableResult
        private func rightConstraint ( _ ardView:UIView?,_ offset: CGFloat,_ alignment: SimplifyAlignment ) -> WrapConstraintMaker{
            return addMakeProcess(ardView){ m,v in m.right.equalTo( self.hRelateTarget(v,alignment) ).offset(offset) }
        }
        
        @discardableResult
        func rightToLeft( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return rightConstraint(ardView,offset,SimplifyAlignment.begin)
        }
        
        @discardableResult
        static func >>< (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.rightConstraint( right.0,right.1,SimplifyAlignment.begin )
        }
        
        @discardableResult
        static func >>< (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left >>< (nil ,right) }
        
        
        @discardableResult
        func rightToCenter( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return rightConstraint(ardView,offset,SimplifyAlignment.middle)
        }
        
        @discardableResult
        static func >>| (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.rightConstraint( right.0,right.1,SimplifyAlignment.middle )
        }
        
        @discardableResult
        static func >>| (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left >>| (nil ,right) }
        
        @discardableResult
        func right( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return rightConstraint(ardView,offset,SimplifyAlignment.end)
        }
        
        @discardableResult
        func rightToParent( _ offset: CGFloat = 0 ) -> WrapConstraintMaker {
            return addMakeProcessImmediately{ $0.right.equalToSuperview().offset(offset) }
        }
        
        @discardableResult
        static func >>> (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.rightConstraint( right.0,right.1,SimplifyAlignment.end )
        }
        
        @discardableResult
        static func >>> (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left >>> (nil ,right) }
        
        //MARK: -------------  顶部约束  ------------------
        @discardableResult
        private func topConstraint ( _ ardView:UIView?,_ offset: CGFloat,_ alignment: SimplifyAlignment ) -> WrapConstraintMaker{
            return addMakeProcess(ardView){ m,v in m.top.equalTo( self.vRelateTarget(v,alignment) ).offset(offset) }
        }
        
        @discardableResult
        func top( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return topConstraint(ardView,offset,SimplifyAlignment.begin)
        }
        
        @discardableResult
        func topToParent( _ offset: CGFloat = 0 ) -> WrapConstraintMaker {
            return addMakeProcessImmediately{ $0.top.equalToSuperview().offset(offset) }
        }
        
        @discardableResult
        static func ^^ (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.topConstraint( right.0,right.1,SimplifyAlignment.begin )
        }
        
        @discardableResult
        static func ^^ (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left ^^ (nil ,right) }
        
        @discardableResult
        func topToCenter( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return topConstraint(ardView,offset,SimplifyAlignment.middle)
        }
        
        @discardableResult
        static func ^- (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.topConstraint( right.0,right.1,SimplifyAlignment.middle )
        }
        
        @discardableResult
        static func ^- (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left ^- (nil ,right) }
        
        
        @discardableResult
        func topToBottom( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return topConstraint(ardView,offset,SimplifyAlignment.end)
        }
        
        @discardableResult
        static func ^~ (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.topConstraint( right.0,right.1,SimplifyAlignment.end )
        }
        
        @discardableResult
        static func ^~ (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left ^~ (nil ,right) }
        
        
        //MARK: -------------  底部约束  ------------------
        @discardableResult
        private func bottomConstraint ( _ ardView:UIView?,_ offset: CGFloat,_ alignment: SimplifyAlignment ) -> WrapConstraintMaker{
            return addMakeProcess(ardView){ m,v in m.bottom.equalTo( self.vRelateTarget(v,alignment) ).offset(offset) }
        }
        
        @discardableResult
        func bottomToTop( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return bottomConstraint(ardView,offset,SimplifyAlignment.begin)
        }
        
        @discardableResult
        static func ~^ (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.bottomConstraint( right.0,right.1,SimplifyAlignment.begin )
        }
        
        @discardableResult
        static func ~^ (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left ~^ (nil ,right) }
        
        @discardableResult
        func bottomToCenter( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return bottomConstraint(ardView,offset,SimplifyAlignment.middle)
        }
        
        @discardableResult
        static func ~- (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.bottomConstraint( right.0,right.1,SimplifyAlignment.middle )
        }
        
        @discardableResult
        static func ~- (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left ~- (nil ,right) }
        
        
        @discardableResult
        func bottom( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return bottomConstraint(ardView,offset,SimplifyAlignment.end)
        }
        
        @discardableResult
        func bottomToParent( _ offset: CGFloat = 0 ) -> WrapConstraintMaker {
            return addMakeProcessImmediately{ $0.bottom.equalToSuperview().offset(offset) }
        }
        
        @discardableResult
        static func ~~ (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.bottomConstraint( right.0,right.1,SimplifyAlignment.end )
        }
        
        @discardableResult
        static func ~~ (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left ~~ (nil ,right) }
        
        //MARK: -------------  水平对齐 ------------------
        @discardableResult
        private func centerXConstraint  ( _ ardView:UIView?,_ offset: CGFloat,_ alignment: SimplifyAlignment )  -> WrapConstraintMaker {
            return addMakeProcess(ardView){ m,v in m.centerX.equalTo( self.hRelateTarget(v,alignment) ).offset(offset) }
        }
        
        @discardableResult
        func centerX( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return centerXConstraint(ardView,offset,SimplifyAlignment.middle)
        }
        
        @discardableResult
        func centerXToParent( _ offset: CGFloat = 0) -> WrapConstraintMaker {
            return addMakeProcessImmediately{ $0.centerX.equalToSuperview().offset(offset) }
        }
        
        @discardableResult
        static func |= (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.centerXConstraint( right.0 , right.1 , SimplifyAlignment.middle )
        }
        
        @discardableResult
        static func |= (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left |= (nil ,right) }
        
        @discardableResult
        func centerXToLeft( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return centerXConstraint(ardView,offset,SimplifyAlignment.begin)
        }
        
        @discardableResult
        static func |< (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.centerXConstraint( right.0 , right.1 , SimplifyAlignment.begin )
        }
        
        @discardableResult
        static func |< (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left |< (nil ,right) }
        
        @discardableResult
        func centerXToRight( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return centerXConstraint(ardView,offset,SimplifyAlignment.end)
        }
        
        @discardableResult
        static func |> (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.centerXConstraint( right.0 , right.1 , SimplifyAlignment.end )
        }
        
        @discardableResult
        static func |> (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left |> (nil ,right) }
        
        //MARK: -------------  垂直对齐 ------------------
        @discardableResult
        private func centerYConstraint  ( _ ardView:UIView?,_ offset: CGFloat,_ alignment: SimplifyAlignment )  -> WrapConstraintMaker {
            return addMakeProcess(ardView){ m,v in m.centerY.equalTo( self.vRelateTarget(v,alignment) ).offset(offset) }
        }
        
        @discardableResult
        func centerY( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return centerYConstraint(ardView,offset,SimplifyAlignment.middle)
        }
        
        @discardableResult
        func centerYToParent( _ offset: CGFloat = 0) -> WrapConstraintMaker {
            return addMakeProcessImmediately{ $0.centerY.equalToSuperview().offset(offset) }
        }
        
        @discardableResult
        static func -- (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.centerYConstraint( right.0,right.1,SimplifyAlignment.middle )
        }
        
        @discardableResult
        static func -- (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left -- (nil ,right) }
        
        @discardableResult
        func centerYToTop( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return centerYConstraint(ardView,offset,SimplifyAlignment.begin)
        }
        
        @discardableResult
        static func -^ (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.centerYConstraint( right.0,right.1,SimplifyAlignment.middle )
        }
        
        @discardableResult
        static func -^ (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left -^ (nil ,right) }
        
        @discardableResult
        func centerYToBottom( _ offset: CGFloat = 0 ,_ ardView:UIView? = nil ) -> WrapConstraintMaker {
            return centerYConstraint(ardView,offset,SimplifyAlignment.end)
        }
        
        @discardableResult
        static func -~ (left: WrapConstraintMaker, right: (UIView?,CGFloat)) -> WrapConstraintMaker {
            return left.centerYConstraint( right.0,right.1,SimplifyAlignment.end )
        }
        
        @discardableResult
        static func -~ (left: WrapConstraintMaker, right:CGFloat ) -> WrapConstraintMaker { return left -~ (nil ,right) }
        
        //MARK: -------------  居中 ------------------
        @discardableResult
        func center( _ ardView: UIView? = nil ) -> WrapConstraintMaker {
            return addMakeProcess(ardView){ m,v in m.center.equalTo( v.snp.center ) }
        }
        
        func centerParent() -> WrapConstraintMaker {
            return addMakeProcessImmediately{ $0.center.equalToSuperview() }
        }
        
        @discardableResult
        static func >><< (left: WrapConstraintMaker, right: UIView? ) -> WrapConstraintMaker {
            return left.center(right)
        }
        
        @discardableResult
        func edges(_ inset:(CGFloat,CGFloat,CGFloat,CGFloat)? = nil, _ ardView: UIView? = nil ) -> WrapConstraintMaker {
            return addMakeProcess(ardView){  $0.edges.equalTo( $1.snp.edges ).inset(UIEdgeInsetsMake(inset?.1 ?? 0, inset?.0 ?? 0, inset?.3 ?? 0, inset?.2 ?? 0)) }
        }
        
        @discardableResult
        func edgesParents(_ left:CGFloat = 0,_ top:CGFloat = 0,_ right:CGFloat = 0,_ bottom:CGFloat = 0) -> WrapConstraintMaker {
            return addMakeProcessImmediately{ $0.edges.equalToSuperview().inset(UIEdgeInsetsMake(top, left, bottom, right )) }
        }
        
        @discardableResult
        static func <<>> (left: WrapConstraintMaker, right: (CGFloat,CGFloat,CGFloat,CGFloat)? ) -> WrapConstraintMaker {
            return left.edges(right)
        }
        
        //MARK: -------------  尺寸 ------------------
        private func width( _ rate:CGFloat = 1 , _ ardView: UIView? = nil , _ isRate:Bool = false , _ isParent:Bool = false ) -> WrapConstraintMaker {
           return addMakeProcess(ardView){ m,v in
                let maker = isParent ? m.width.equalToSuperview() : m.width.equalTo( v.snp.width )
                let _ = isRate ? maker.multipliedBy(rate) : maker.offset(rate)
            }
        }
        
        @discardableResult
        func widthByRate( _ rate:CGFloat = 1 , _ ardView: UIView? = nil ) -> WrapConstraintMaker {
            return width(rate,ardView,true,false)
        }
        
        @discardableResult
        func widthByOffset( _ rate:CGFloat = 1 , _ ardView: UIView? = nil ) -> WrapConstraintMaker {
            return width(rate,ardView,false,false)
        }
        
        @discardableResult
        func width( _ size:CGFloat) -> WrapConstraintMaker {
            allMakers.append{
                $0.width.equalTo(size)
            }
            return self
        }
        
        @discardableResult
        func widthToParentByRate( _ rate:CGFloat = 1) -> WrapConstraintMaker {
            return width(rate,nil,true,true)
        }
        
        @discardableResult
        func widthToParent( _ rate:CGFloat = 1) -> WrapConstraintMaker {
            return addMakeProcessImmediately {
                $0.width.equalToSuperview().multipliedBy(rate)
            }
        }
        
        private func height( _ rate:CGFloat = 1 , _ ardView: UIView? = nil , _ isRate:Bool = false , _ isParent:Bool = false ) -> WrapConstraintMaker {
            return addMakeProcess(ardView){ m,v in
                let maker = isParent ? m.height.equalToSuperview() : m.height.equalTo( v.snp.height )
                let _ = isRate ? maker.multipliedBy(rate) : maker.offset(rate)
            }
        }
        
        @discardableResult
        func heightByRate( _ rate:CGFloat = 1 , _ ardView: UIView? = nil ) -> WrapConstraintMaker {
            return height(rate,ardView,true,false)
        }
        
        @discardableResult
        func heightByOffset( _ rate:CGFloat = 0 , _ ardView: UIView? = nil ) -> WrapConstraintMaker {
            return height(rate,ardView,false,false)
        }
        
        @discardableResult
        func height( _ size:CGFloat) -> WrapConstraintMaker {
            allMakers.append{
                $0.height.equalTo(size)
            }
            return self
        }
        
        @discardableResult
        func heightToParent( _ rate:CGFloat = 0) -> WrapConstraintMaker {
            return addMakeProcessImmediately {
                $0.height.equalToSuperview().multipliedBy(rate)
            }
        }
        
        //MARK: -------------  等边 ------------------
        @discardableResult
        func equilateral(_ size:CGFloat) -> WrapConstraintMaker {
            return addMakeProcessImmediately {
                $0.width.equalTo(size)
                $0.height.equalTo(size)
            }
        }
        
        @discardableResult
        func equilateralToParent(_ hRate:CGFloat = 1 ,_ vRate:CGFloat = 1) -> WrapConstraintMaker {
            return addMakeProcessImmediately {
                $0.width.equalToSuperview().multipliedBy(hRate)
                $0.height.equalToSuperview().multipliedBy(vRate)
            }
        }
        
        func horizontalToParent(_ leftMargin:CGFloat = 0 ,_ rightMargin:CGFloat = 0) -> WrapConstraintMaker {
            return addMakeProcessImmediately {
                $0.left.equalToSuperview().offset(leftMargin)
                $0.right.equalToSuperview().offset(rightMargin)
            }
        }
        
        func verticalToParent(_ topMargin:CGFloat = 0 ,_ bottomMargin:CGFloat = 0) -> WrapConstraintMaker {
            return addMakeProcessImmediately {
                $0.top.equalToSuperview().offset(topMargin)
                $0.bottom.equalToSuperview().offset(bottomMargin)
            }
        }
        
        //MARK: -------------  自定义 ------------------
        @discardableResult
        func custom(_ maker:@escaping (ConstraintMaker)-> Void) -> WrapConstraintMaker  {
            allMakers.append(maker)
            return self
        }
        
        //MARK: -------------  从新设置 ------------------
        func reSet(){
            ( mineView ?? self.cacheView )?.snp.remakeConstraints{ buildMakes($0) }
        }
        
        func update(){
            ( mineView ?? self.cacheView )?.snp.updateConstraints{ buildMakes($0) }
        }
        
        //支持多个下标修改  不支持 忽略 (因为view没有缓存  防止内存泄露)
        subscript(_ indexs: Int... ) -> (WrapConstraintMaker)-> Void {
            get{ return {_ in } }
            set{
                stashMakers = [( (ConstraintMaker)-> Void )]()
                newValue(self)
                let allMakeRange = Range(0..<allMakers.count)
                indexs.forEach{ index in
                    if stashMakers!.count > 0 && allMakeRange.contains(index) {
                        allMakers[index] = stashMakers!.remove(at: 0)
                    }
                }
                stashMakers?.removeAll()
                stashMakers = nil
                reSet()
            }
        }
        
    }
    
    

    相关文章

      网友评论

          本文标题:冰清玉洁的IOS代码---精简SnapKit

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