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

2018-06-13  本文已影响105人  747a945a4501

前言

由于新工作只做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()
        }
    }
    
}

上一篇下一篇

猜你喜欢

热点阅读