開源 Swift AutoLayout 框架 SnapKit 介紹

自從水果發佈了5代,蘋果爲了適配多種屏幕尺寸,搞出了一個所謂的AutoLayout來解決問題,iOS程序員們今後走上了苦逼的適配路。git

「適配」自己其實並非一個頭疼的事情,對於4-6寸的手機來講,只要制定一套規則,就不會有太大的問題。可是令我痛苦的部分在於——iOS的 Constraints 和 VFL。程序員

痛苦的NSLayoutConstraints

這裏借用iOS開源項目 Masonry 的描述,假如咱們要讓一個view在superview里居中,而後每條邊留出10像素的空白,代碼是這樣寫的:github

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[superview addConstraints:@[

    //view1 constraints
    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeTop
                                multiplier:1.0
                                  constant:padding.top],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeLeft
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeLeft
                                multiplier:1.0
                                  constant:padding.left],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeBottom
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1.0
                                  constant:-padding.bottom],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeRight
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeRight
                                multiplier:1
                                  constant:-padding.right],

 ]];

若是你剛剛接觸iOS開發,你可能認爲這並非什麼問題。可是讓咱們作個對比,在web開發中,應該怎麼寫呢?web

#view{margin:10px;}

一行代碼搞定問題,CSS是世界上最偉大的排版引擎,沒有之一。明明很簡單的事情,爲何放到iOS上,居然變得這麼這麼這麼複雜了?swift

仍然痛苦的VFL

而後蘋果又搞出了VFL,網上對此描述最多的是「象形文字」,雖然它真的真的改善了咱們建立constraints的方式,讓這一切變得更快更方便,可是對於下面這段代碼,我仍然是不滿的。less

constraints += NSLayoutConstraint.constraintsWithVisualFormat("V:[trackBtn]-15-[filterBtn(40)]-15-|", options: NSLayoutFormatOptions.AlignAllRight, metrics: nil, views: views)
constraints += NSLayoutConstraint.constraintsWithVisualFormat("[trackBtn]-15-|", options: NSLayoutFormatOptions.AlignmentMask, metrics: nil, views: views)
constraints += NSLayoutConstraint.constraintsWithVisualFormat("|-15-[filterBtn]-15-|", options: NSLayoutFormatOptions.AlignmentMask, metrics: nil, views: views)

莫名其妙的options,metrics和views參數的組合,長成狗同樣的函數名。並且即便是有了VFL,咱們仍是離不開 constraints ,VFL並無真的知足咱們的全部需求,好比你看看 這個需求函數

那麼,咱們是否是隻能一聲嘆氣,說,iOS的世界就這樣了呢?動畫

NO!!!咱們有Masonry和SnapKit!!!spa

SnapKit能搞定什麼

SnapKit是Masonry的Swift版,項目發佈至今大約1年的時間,已經在github上有兩千多個star,固然了,這其中也少不了"他爹"Masonry給他打的那些廣告。code

若是你還記得你在 StoryBoard 裏面拉的那些線條,那你也必定記得其中 constriants 的表示方法:

SnapKit所作的就是這樣一件事——讓你這樣寫 constraints。

咱們看看文章最頂部的那個需求用 SnapKit 如何實現:

view1.snp_makeConstraints { (make) -> Void in
    make.top.equalTo(superview).offset(10)
    make.left.equalTo(superview).offset(10)
    make.bottom.equalTo(superview).offset(-10)
    make.right.equalTo(superview).offset(-10)
}

對!就是這麼簡單!還能夠更簡單!!

view1.snp_makeConstraints { (make) -> Void in
    make.edges.equalTo(superview).insets(UIEdgeInsetsMake(10, 10, 10, 10))
}

來,請跟我一塊兒大叫三聲爽!

爽!

爽!

叫完以後咱們繼續看還能怎麼爽:

// 不僅是相等哦,大於等於也是有的
make.centerX.lessThanOrEqualTo(view2.snp_left)
make.left.greaterThanOrEqualTo(label.snp_left)

// 不止是邊緣哦,寬度高度也是有的
// width >= 200 && width <= 400
make.width.greaterThanOrEqualTo(200)
make.width.lessThanOrEqualTo(400)

// 其實能夠簡單點,一行搞定一個size
make.size.equalTo(CGSizeMake(50, 100))

// 鏈式操做,優先級想怎麼搞就怎麼搞
make.left.greaterThanOrEqualTo(label.snp_left).priorityLow()

// 媽媽不再擔憂我不會排版了,什麼向左5像素向下10像素我一行代碼就搞定啦
make.center.equalTo(superview).offset(CGPointMake(-5, 10))

作起動畫來也是一把好手!

view1.snp_makeConstraints { (make) -> Void in
  self.topConstraint = make.top.equalTo(superview).offset(padding.top).constraint
  make.left.equalTo(superview).offset(padding.left)
}

// then later you can call
self.topConstraint.uninstall()

// or if you want to update the constraint
self.topConstraint.updateOffset(5)

// 也能夠用 snp_updateConstraints 實現上述需求

這麼好的東西,我去哪裏搞!

若是你用CocoaPods,那麼Podfile你懂的:

pod 'SnapKit', :git => 'https://github.com/SnapKit/SnapKit.git', :branch => 'swift-2.0'

若是你用Carthege……這個我沒用過我就不瞎說了……

總之呢,不用CocoaPods的朋友能夠去 這裏 下載,至於怎麼弄進項目我就無論了(好好滴乾嗎不用CocoaPods..)

成果

我用SnapKit作了下面這個界面:

體驗以後發現,其實用SnapKit和原生constraints的代碼行數差很少,可是每一行從原來的極爲冗長的一坨東西,變成了很容易閱讀和維護的短小精幹的代碼,代碼像下面這樣優雅,這即是SnapKit最大的做用。

mapView.snp_makeConstraints { (make) -> Void in
    make.edges.equalTo(view)
}
locateImage.snp_makeConstraints { (make) -> Void in
    let topHeight = navigationController!.navigationBar.frame.height + UIApplication.sharedApplication().statusBarFrame.height
    make.centerX.equalTo(mapView)
    make.bottom.equalTo(mapView.snp_centerY).offset(topHeight/2)
}
filterBtn.snp_makeConstraints { (make) -> Void in
    make.left.equalTo(mapView).offset(15)
    make.right.equalTo(mapView).offset(-15)
    make.height.equalTo(40)
    make.bottom.equalTo(mapView).offset(-15)
}
trackBtn.snp_makeConstraints { (make) -> Void in
    make.bottom.equalTo(filterBtn.snp_top).offset(-15)
    make.right.equalTo(mapView).offset(-15)
}
相關文章
相關標籤/搜索