最好用的iOS快速布局UI庫

原文地址:http://www.reibang.com/p/ac47c4826a19

NerdyUI

最好用的快速布局 UI 庫沉衣,適用于 iOS 8 及以上版本涮较。

github:https://github.com/nerdycat/NerdyUI

相關文章:

NerdyUI 使用小技巧

序言

眾所周知获洲,UI在一個App中所占的比重是很大的,如果能快速的布局UI程拭,就能大大的提高App的整體開發(fā)效率建蹄,NerdyUI正是基于這個理由創(chuàng)建的。

NerdyUI使用非常緊湊的鏈式語法动看,提供一些常用但系統(tǒng)控件又缺失的功能尊剔,更為簡便的約束創(chuàng)建方式和更好理解的布局系統(tǒng),勢必能大大減少您的代碼量和開發(fā)時間菱皆。

快速創(chuàng)建 NSString, UIFont, UIColor, UIImage 和常用的 structs

你可以用Str()來轉(zhuǎn)換大部分類型到NSString须误。同理,你可以用Log()來打印大部分的變量仇轻。

Str(100);//@"100"Str(3.14);//@"3.14"Str(@0.618);//@"0.618"Str(view.frame);//@"{{0, 0}, {100, 100}}"Str(view.center);//@"{50, 50}"Str(_cmd);//@"viewDidLoad"Str(NSString.class);//@"NSString"Str("C-String");//@"C-String"Str(@"1 + 1 = %d",1+1);//@"1 + 1 = 2Log(100);Log(3.14);Log(@0.618);Log(view.frame);...Log(@"1 + 1 = %d",1+1);//拼接字符串@"1".a(@"2").a(3).a(nil).a(4.0f).a(@5).a(@"%d",6);//@"123456"

你可以用AttStr()來創(chuàng)建NSAttributedString京痢。

AttStr(@"hello, 101").match(@"[0-9]+").underline;//給101加下劃線AttStr(@"A smile ", Img(@"smile"), @" !!");//帶圖片的NSAttributedString

你可以用Fnt()來創(chuàng)建UIFont。

Fnt(15);//[UIFont systemFontOfSize:15]Fnt(@15);//[UIFont boldSystemFontOfSize:15]Fnt(@"body");//UIFontTextStyleBodyFnt(@"Helvetica,15");//helvetica font with size 15

你可以用Color()來創(chuàng)建UIColor篷店。

Color(@"red");//[UIColor redColor]Color(@"0,0,255");//RGB colorColor(@"#0000FF");//Hex colorColor(@"random");//random color//以上這些還可以有一個可選的alpha參數(shù)Color(@"red,0.5");//red color with alpha 0.5Color(@"0,0,255,0.8");//blue color with alpha 0.8...Color(Img(@"pattern"));//pattern image color

你可以用Img()來創(chuàng)建UIImage祭椰。

Img(@"imageName");//[UIImage imageNamed:@"imageName"]Img(@"#imageName");//加上#號會返回一個可拉伸的圖片,拉伸位置在圖片中心Img(@"red");//返回一個 1x1 大小的紅色圖片疲陕,可用在某些需要純色圖片的地方

你可以用XY(),WH(),XYWH(),Range(),Insets()來創(chuàng)建CGPoint, CGSize, CGRect, NSRange, UIEdgeInsets方淤。XYWH()和Insets()支持多種創(chuàng)建方式。

CGPoint? ? ? ? p = XY(20,20);CGSize? ? ? ? s = WH(50,50);CGRect? ? ? ? f1 = XYWH(20,20,50,50);CGRect? ? ? ? f2 = XYWH(f1.origin, f1.size);CGRect? ? ? ? f3 = XYWH(f2.origin,50,50);CGRect? ? ? ? f4 = XYWH(20,20, f3.size);NSRange? ? ? ? r = Range(10,20);UIEdgeInsets i1 = Insets(10);//{10, 10, 10, 10}UIEdgeInsets i2 = Insets(10,20);//{10, 20, 10, 20}UIEdgeInsets i3 = Insets(10,20,30);//{10, 20, 30, 20}UIEdgeInsets i4 = Insets(10,20,30,40);//{10, 20, 30, 40}

使用這些宏可以簡化一些常見類型的創(chuàng)建過程蹄殃,更重要的是你可以用同樣的方式來設置視圖的屬性值携茂,稍后你就會明白這是什么意思。

快速訪問frame屬性和屏幕大小

someView.x =10;someView.y = someView.x;someView.xy = XY(10,10);someView.w =50;//widthsomeView.h = someView.w;//heightsomeView.wh = WH(50,50);someView.frame = XYWH(10,10,50,50);someView.cx =25;someView.cy = someView.cx;someView.center = XY(25,25);someView.maxX =60;someView.maxY = someView.maxX;someView.maxXY = XY(60,60);//Screen只是 [UIScreen mainScreen] 的宏定義someView.wh = WH(Screen.width, Screen.height);

我猜大部分人都有類似的擴展吧

快速的創(chuàng)建UI控件

NerdyUI 使用鏈式語法來快速的創(chuàng)建和設置 UI 控件诅岩。

UIView *view1 = View.xywh(20,30,50,50).bgColor(@"red").opacity(0.7).border(3, @"3d3d3d");UIView *view2 = View.xy(80,30).wh(view1.wh).bgColor(@"blue,0.7").borderRadius(25).shadow(0.8).onClick(^{? ? Log(@"view2");});

view

UIImageView *moose = ImageView.img(@"moose").x(20).y(100).shadow(0.6,2,-3,-1);UILabel *quiz = Label.str(@"%d+%d=?",1,1).fnt(@17).color(@"66,66,66").fitSize.x(moose.maxX +10).cy(moose.cy);

moose

//如果后續(xù)不需要再訪問 title 的屬性讳苦,定義為 id 可以減少一些代碼量id title = AttStr(@"TAP ME").fnt(15).underline.range(0,3).fnt(@18).color(@"random");UIButton *button1 = Button.str(title).insets(5,10).fitSize.border(1).xy(20,150).onClick(^(UIButton *btn) {//Exp() 可在任何位置執(zhí)行任意代碼quiz.text = Str(@"%d+%d=%d",1,1, Exp(btn.tag +=1));? ? [quiz sizeToFit];});UIButton *button2 = Button.str(@"HAT").highColor(@"brown").img(@"hat").gap(8);button2.xywh(button1.frame).x(button1.maxX +10).borderRadius(5).bgImg(@"blue,0.5").highBgImg(@"orange");//.highBgImg() 可以用來設置 UIButton 的 highlightedBackgroundColor,這是一個非常有用的功能

button

id pinField = TextField.x(button1.x).y(button1.maxY +15).wh(170,30).onChange(^(NSString *text) {//這里的 self 已經(jīng)自動做了 weakify 處理, 不用擔心會有引用循環(huán)[(id)[self.view viewWithTag:101]setText:text];}).numberKeyboard.maxLength(4).hint(@"pin code").fnt(15).roundStyle;id textView = TextView.xywh(20,240,170,100).border(1).insets(8).hint(@"placeholder").fnt([pinField font]).tg(101);

input

正如你所看到的按厘,大部分鏈式屬性還是比較簡單明了的医吊。有一些屬性非常的靈活,可以接受不同類型的參數(shù)逮京。順便說一下卿堂,View只是[UIView new]的宏定義,Label只是[UILabel new]的宏定義,其他幾個UI類也一樣(就是類名去掉 UI )草描。

你可以用.opacity()和.tg()來設置視圖的 alpha 和 tag 值.

你可以用.x(),.y(),.xy(),.w(),.h(),.wh(),.xywh(),.cx(),.cy(),.cxy(),.maxX(),.maxY(),.maxXY()等來設置視圖的大小和位置览绿。

你可以用.touchEnabled,.touchDisabled,.invisible來設置視圖是否可點和是否可見。

你可以用.flexibleLeft,.flexibleRight,.flexibleTop,.flexibleBottom,.flexibleLR,.flexibleTB,.flexibleLRTB,.flexibleWidth,.flexibleHeight,.flexibleWH等來設置autoresizingMask穗慕。

你可以用.centerAlignment,.rightAlignment等來設置對齊屬性饿敲。

你可以用.fnt()來設置字體,它能接受的參數(shù)跟Fnt()一樣逛绵。

你可以用.str()來設置 text 或者 attribtedText怀各, 它能接受的參數(shù)跟Str()一樣。

你可以用.img(),.highImg(),.bgImg()和.highBgImg()來設置 image, highlightedImage, backgroundImage 和 highlightedBackgroundImage术浪。 他們能接受的參數(shù)跟Img()一樣瓢对。

你可以用.tint(),.color(),.bgColor(),.highColor()來設置 tintColor, textColor, backgroundColor 和 highlightedTextColor, 它們能接受的參數(shù)跟Color()一樣。

你可以用.border(),.borderRadius()和.shadow()來設置邊框和陰影胰苏。

你可以用.fitWidth,.fitHeight和.fitSize來改變視圖的大小硕蛹,使它的大小剛好能包含視圖的內(nèi)容。

你可以用.onClick()來給任何視圖添加一個單擊事件硕并。

至于 UITextField? 和 UITextView, 你可以用.hint()來設置 placeholder,.maxLength()來限制輸入文本的長度,.onChange()來添加一個文本改變事件法焰。

如果是 UIButton, UITextField 和 UITextView, 你還可以使用.insets()來添加一些padding。

這里列出的只是一部分屬性倔毙,你可以到對應的擴展頭文件里看完整的屬性列表埃仪。

UILabel擴展

以前如果想給UILabel添加行間距,必須使用NSAttributedString∩略撸現(xiàn)在你只需要使用.lineGap()設置一下就行了贵试。

另一個很有的擴展功能是鏈接,你只需要使用AttStr()來創(chuàng)建一個NSAttributedString凯正, 并標記其中一部分為.linkForLabel,那么標記的那部分自動就會變成鏈接豌蟋。然后你只需要用.onLink()來給UILabel 添加一個鏈接點擊事件就行了廊散。

idstr= @"Lorem ipsum 20 dolor sit er elit lamet, consectetaur cillium #adipisicing pecu, sed do #eiusmod tempor incididunt ut labore et 3.14 dolore magna aliqua.";id attStr = AttStr(str).range(0,5).match(@"lamet").match(@"[0-9.]+").matchHashTag.linkForLabel;Label.str(attStr).multiline.lineGap(10).xywh(self.view.bounds).onLink(^(NSString *text) {? ? Log(text);}).addTo(self.view);

label

快速的創(chuàng)建約束

有的時候手動修改 frame 會顯得很麻煩。NerdyUI 提供一些鏈式屬性和一個跟 Masonry 類似的方式來創(chuàng)建約束梧疲。

你可以用.fixWidth(),.fixHeight(),.fixWH()來添加寬高約束允睹。

你可以用.embedIn()來把一個視圖嵌入到它的父視圖里, 這會添加上下左右的約束幌氮。

你可以用.horHugging(),.horResistance(),.verHugging(),.verResistance(),.lowHugging,.lowResistance,.highHugging和.highResistance來設置 contentHuggingPriority 和 contentCompressionResistancePriority缭受。當有多個視圖在 StackView 里時,可以用這些屬性來設置允許哪些視圖可以拉伸该互,哪些視圖不可以拉伸米者。

對于更復雜的約束, 你可以用.makeCons(),.remakeCons()和.updateCons()來設置約束, 就像Masonry一樣。

ImageView.img(@"macbook").embedIn(self.view).centerMode;id hello =Label.str(@"HELLO").fnt(@20).wh(80, 80).centerAlignment;idmac=Label.str(@"MAC").fnt(@20).wh(80, 80).centerAlignment;//使用 .makeCons() 之前必須把當前視圖加到父視圖里蔓搞,這里使用 .addTo() 來執(zhí)行此操作EffectView.darkBlur.fixWH(80, 80).addTo(self.view).makeCons(^{//在 .makeCons() 里你可以直接使用 make 變量胰丁,不需要顯示的定義它make.right.equal.superview.centerX.constants(0);? ? make.bottom.equal.superview.centerY.constants(0);}).addVibrancyChild(hello).tg(101);EffectView.extraLightBlur.fixWidth(80).fixHeight(80).addTo(self.view).makeCons(^{? ? make.left.bottom.equal.view(self.view).center.constants(0, 0);});EffectView.lightBlur.addTo(self.view).makeCons(^{? ? make.size.equal.constants(80, 80).And.center.equal.constants(40, 40);}).addVibrancyChild(mac);id subImg = Img(@"macbook").subImg(95, 110, 80, 80).blur(10);ImageView.img(subImg).addTo(self.view).makeCons(^{? ? make.centerX.top.equal.view([self.viewviewWithTag:101]).centerX.bottom.constants(0);});

constraints

快速布局

手動給每個視圖添加約束稍微想一下就知道會很麻煩。幸好大部分的 UI 可以用HorStack()和VerStack()來實現(xiàn)喂分。使用這兩個簡易版 StackView锦庸,加上上面介紹的那幾個屬性,很多時候你根本不需要手動顯示的創(chuàng)建任何約束蒲祈。

_indexLabel = Label.fnt(17).color(@"darkGray").fixWidth(44).centerAlignment;_iconView = ImageView.fixWH(64,64).borderRadius(10).border(Screen.onePixel, @"#CCCCCC");//用 .preferWidth() 來設置 preferredMaxLayoutWidth甘萧,有助于提高性能_titleLabel = Label.fnt(15).lines(2).preferWidth(Screen.width -205);_categoryLabel = Label.fnt(13).color(@"darkGray");_ratingLabel = Label.fnt(11).color(@"orange");_countLabel = Label.fnt(11).color(@"darkGray");_actionButton = Button.fnt(@15).color(@"#0065F7").border(1, @"#0065F7").borderRadius(3);_actionButton.highColor(@"white").highBgImg(@"#0065F7").insets(5,10);_iapLabel = Label.fnt(9).color(@"darkGray").lines(2).str(@"In-App\nPurchases").centerAlignment;//.gap() 會在每一個StackView Item 之間添加間隙id ratingStack = HorStack(_ratingLabel, _countLabel).gap(5);id midStack = VerStack(_titleLabel, _categoryLabel, ratingStack).gap(4);id actionStack = VerStack(_actionButton, _iapLabel).gap(4).centerAlignment;HorStack(? ? ? ? _indexLabel,? ? ? ? _iconView,? ? ? ? @10,//使用NSNumber可在兩個 Item 之間添加間隙midStack,? ? ? ? NERSpring,//NERSpring是一個特殊的變量,它相當于一個彈簧梆掸,保證actionStack始終停留在最右邊actionStack).embedIn(self.contentView,10,0,10,15);

appcell

這里我們模仿 AppStore 排行榜來創(chuàng)建一個類似的 Cell 扬卷。可以看出 HorStack (橫向) 和 VerStack (豎向)

的用法非常的簡單沥潭。你只需要找出最小的 Stack 邀泉,然后把它嵌到上一層的 Stack 里,重復這個過程直到最外層的 Stack 用

embedIn 來添加到它的父視圖里钝鸽。最后你還可以給這些視圖加上一些間隙(gap)汇恤。

使用 "Debug View Hierarchy" 可以看到這些視圖是怎么嵌套再一起的。

appcell2

一旦布局完拔恰,剩下的就是設置要顯示的內(nèi)容因谎,其他的都不需要再動了。

輕量級 Style

大部分鏈式屬性都可以設置為 style颜懊。

//全局StyleStyle(@"h1").color(@"#333333").fnt(17);Style(@"button").fixHeight(30).insets(0,10).borderRadius(5);//局部Styleid actionButtonStyle = Style().styles(@"button h1").bgImg(@"red").highBgImg(@"blue").highColor(@"white");

這里我們創(chuàng)建了兩個全局 Style 和一個局部 Style财岔。局部 Style 使用.styles()來繼承那兩個全局 Style。創(chuàng)建完之后河爹,全局 Style 可以使用 Style 名來全局引用匠璧,局部 Style 只能使用變量名來引用。所有的 UIView(及其子類) 和 NSAttributedString 都可以引用這些 Style咸这。

id foo= Label.styles(@"h1").str(@"hello world");id bar= Button.styles(actionButtonStyle).str(@"Send Email");

其他

你可以用PlainTV和GroupTV來創(chuàng)建靜態(tài)的 UITableView夷恍,比如說設置頁面。

PlainTV(Row.str(@"Row1"), Row.str(@"Row2"), Row.str(@"Row3")).embedIn(self.view);

你可以用Alert和ActionSheet來創(chuàng)建并顯示 UIAlert 和 UIActionSheet媳维。

Alert.title(@"Title").message(@"Message").action(@"OK",^{}),cancel(@"Cancel").show();ActionSheet.title(@"Title").message(@"Message").action(@"OK",^{}),cancel(@"Cancel").show();

對于NSArray, 我們提供了.forEach(),.map(),.filter()和.reduce()等這幾個鏈式屬性酿雪。

id result = @[@1, @2, @3, @4].map(^(NSInteger n) {returnn *2;}).filter(^(NSInteger n) {returnn <5;}).reduce(^(NSInteger ac, NSInteger n) {returnac + n;});

注意

在鏈式屬性里直接使用中文字符串常量會導致后續(xù)的自動補全提示失效,一個解決方案是把中文字符串單獨拿出來定義為一個變量侄刽,或者把.str(),.hint()等 放在最后面指黎。

當你使用.onClick(),.onLink(),.onChange()和.onFinish()時, 里面的self已經(jīng)做了 weakify 處理了州丹,所以你不需要擔心會有引用循環(huán)問題醋安。有時候你可能需要對它做個強引用來保證它不會被提前釋放。這幾個屬性除了可以傳一個 block 之外,還可以傳一個方法名來作為回調(diào)方法茬故。

NerdyUI 使用了非常多的宏定義和類別方法盖灸,而且為了方便使用沒添加任何前綴。雖然所有的名字都是經(jīng)過精心挑選的磺芭,不排除有跟您自己代碼或其他第三方庫沖突的可能赁炎,請注意。

用CocoaPods安裝

pod"NerdyUI"

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钾腺,一起剝皮案震驚了整個濱河市徙垫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌放棒,老刑警劉巖姻报,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異间螟,居然都是意外死亡吴旋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門厢破,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荣瑟,“玉大人,你說我怎么就攤上這事摩泪“恃妫” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵见坑,是天一觀的道長嚷掠。 經(jīng)常有香客問我,道長荞驴,這世上最難降的妖魔是什么不皆? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮熊楼,結果婚禮上粟焊,老公的妹妹穿的比我還像新娘。我一直安慰自己孙蒙,他們只是感情好,可當我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布悲雳。 她就那樣靜靜地躺著挎峦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪合瓢。 梳的紋絲不亂的頭發(fā)上坦胶,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天,我揣著相機與錄音,去河邊找鬼顿苇。 笑死峭咒,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的纪岁。 我是一名探鬼主播凑队,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼幔翰!你這毒婦竟也來了漩氨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤遗增,失蹤者是張志新(化名)和其女友劉穎叫惊,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體做修,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡霍狰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了饰及。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔗坯。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖旋炒,靈堂內(nèi)的尸體忽然破棺而出步悠,到底是詐尸還是另有隱情,我是刑警寧澤瘫镇,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布鼎兽,位于F島的核電站,受9級特大地震影響铣除,放射性物質(zhì)發(fā)生泄漏谚咬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一尚粘、第九天 我趴在偏房一處隱蔽的房頂上張望择卦。 院中可真熱鬧,春花似錦郎嫁、人聲如沸秉继。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尚辑。三九已至,卻和暖如春盔腔,著一層夾襖步出監(jiān)牢的瞬間杠茬,已是汗流浹背月褥。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓢喉,地道東北人宁赤。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像栓票,于是被迫代替她去往敵國和親决左。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容