精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

實時顯示iOS編寫UI代碼效果

移動開發(fā)
編寫iOS應用UI的方式大概有兩種,一種是Storyboard/Xib,另一種是手寫代碼。采用Storyboard/Xib方式組織UI,由于提供可視化的特性,只要從UI庫中拖動UI控件,便可以顯示結果,極大地提高開發(fā)速度。但面臨一個問題就是多人協(xié)作開發(fā),由于所有的UI都放在同一個Storyboard文件中,使用Git/SVN合并代碼就會出現(xiàn)沖突。多人協(xié)作開發(fā)還不是主要問題,有人提出可以創(chuàng)建多個Storyboard來分開UI編寫,而Storyboard/Xib最主要問題是代碼復用性比較差。所以有些人就選擇手寫UI代碼,這樣不僅可以解決多人協(xié)作開發(fā)問題,而且通過自定義控件在多個View使

[[144355]]

編寫iOS應用UI的方式大概有兩種,一種是Storyboard/Xib,另一種是手寫代碼。采用Storyboard/Xib方式組織UI,由于提供可視化的特性,只要從UI庫中拖動UI控件,便可以顯示結果,極大地提高開發(fā)速度。但面臨一個問題就是多人協(xié)作開發(fā),由于所有的UI都放在同一個Storyboard文件中,使用Git/SVN合并代碼就會出現(xiàn)沖突。多人協(xié)作開發(fā)還不是主要問題,有人提出可以創(chuàng)建多個Storyboard來分開UI編寫,而Storyboard/Xib最主要問題是代碼復用性比較差。所以有些人就選擇手寫UI代碼,這樣不僅可以解決多人協(xié)作開發(fā)問題,而且通過自定義控件在多個View使用。但每次手寫UI代碼后都要編譯、構建和運行,***在模擬器顯示,這樣會拖慢開發(fā)速度。如果每次修改UI控件后,保存修改便實時在模擬器顯示修改后結果,就可以極大的提高編寫UI的速度。

Live Change.gif

 

Auto Layout

Auto Layout是什么

Auto Layout是一個基于constraint(約束)的布局系統(tǒng),它根據(jù)UI元素之間約束關系來調(diào)整UI元素的位置和大小。

Auto Layout解決什么問題

  • 更容易適配不同分辨率設備的屏幕(iPhone 6 Plus, iPhone 6, iPhone 5s/5, iPhone 4s/4)
  • 當設備旋轉(zhuǎn)時不需要做額外處理
  • 使用constraint來描述布局邏輯,更利于理解和清晰

如何使用Auto Layout

Auto Layout中約束的類對應是NSLayoutConstraint, 而創(chuàng)建NSLayoutConstraint對象主要有兩種方式,***種是

  1. + (id)constraintWithItem:(id)view1 
  2.                attribute:(NSLayoutAttribute)attribute1 
  3.                relatedBy:(NSLayoutRelation)relation 
  4.                   toItem:(id)view2 
  5.                attribute:(NSLayoutAttribute)attribute2 
  6.               multiplier:(CGFloat)multiplier 
  7.                 constant:(CGFloat)constant; 

上面方法主要意思是,某個view1的attribute1等于(小于或等于/大于或等于)某個view2的attribute2的multiplier倍加上constant。而attribute主要由表示位置(上/下/左/右)和大小(寬/高)的以下幾個值:

  1. typedef enum: NSInteger { 
  2.    NSLayoutAttributeLeft = 1
  3.    NSLayoutAttributeRight, 
  4.    NSLayoutAttributeTop, 
  5.    NSLayoutAttributeBottom, 
  6.    NSLayoutAttributeLeading, 
  7.    NSLayoutAttributeTrailing, 
  8.    NSLayoutAttributeWidth, 
  9.    NSLayoutAttributeHeight, 
  10.    NSLayoutAttributeCenterX, 
  11.    NSLayoutAttributeCenterY, 
  12.    NSLayoutAttributeBaseline, 
  13.    NSLayoutAttributeNotAnAttribute = 0 
  14. } NSLayoutAttribute; 

簡化一下,使用公式可以表達為:

  1. view1.attribute1 = view2.attribute2 * multiplier + constant 

第二種方式是:

  1. + (NSArray *)constraintsWithVisualFormat:(NSString *)format  
  2.                                  options:(NSLayoutFormatOptions)opts  
  3.                                  metrics:(NSDictionary *)metrics  
  4.                                    views:(NSDictionary *)views; 

這種方式主要是采用Visual Format Language(可視化格式語言)來描述約束布局,雖然語法比較簡潔,但是可讀性比較差和容易出錯。

Auto Layout存在問題

雖然Auto Layout在布局view方面是非常強大和靈活,但是創(chuàng)建constraint的語法過于繁雜,引用Masonry一個例子:

  1. UIView *superview = self; 
  2.  
  3. UIView *view1 = [[UIView alloc] init]; 
  4. view1.translatesAutoresizingMaskIntoConstraints = NO; 
  5. view1.backgroundColor = [UIColor greenColor]; 
  6. [superview addSubview:view1]; 
  7.  
  8. UIEdgeInsets padding = UIEdgeInsetsMake(10101010); 
  9.  
  10. [superview addConstraints:@[ 
  11.  
  12.     //view1 constraints 
  13.     [NSLayoutConstraint constraintWithItem:view1 
  14.                                  attribute:NSLayoutAttributeTop 
  15.                                  relatedBy:NSLayoutRelationEqual 
  16.                                     toItem:superview 
  17.                                  attribute:NSLayoutAttributeTop 
  18.                                 multiplier:1.0 
  19.                                   constant:padding.top], 
  20.  
  21.     [NSLayoutConstraint constraintWithItem:view1 
  22.                                  attribute:NSLayoutAttributeLeft 
  23.                                  relatedBy:NSLayoutRelationEqual 
  24.                                     toItem:superview 
  25.                                  attribute:NSLayoutAttributeLeft 
  26.                                 multiplier:1.0 
  27.                                   constant:padding.left], 
  28.  
  29.     [NSLayoutConstraint constraintWithItem:view1 
  30.                                  attribute:NSLayoutAttributeBottom 
  31.                                  relatedBy:NSLayoutRelationEqual 
  32.                                     toItem:superview 
  33.                                  attribute:NSLayoutAttributeBottom 
  34.                                 multiplier:1.0 
  35.                                   constant:-padding.bottom], 
  36.  
  37.     [NSLayoutConstraint constraintWithItem:view1 
  38.                                  attribute:NSLayoutAttributeRight 
  39.                                  relatedBy:NSLayoutRelationEqual 
  40.                                     toItem:superview 
  41.                                  attribute:NSLayoutAttributeRight 
  42.                                 multiplier:1 
  43.                                   constant:-padding.right], 
  44.  
  45.  ]]; 

如此簡單的一個例子都要編寫這么多行代碼,想象一下如果創(chuàng)建多個view的constraint時會多么痛苦啊。另一個方式是采用Visual Format Language (VFL),雖然語法比較簡潔,但是可讀性比較差和容易出錯。

Masonry

為什么使用Masonry

Masonry是采用鏈式DSL(Domain-specific language)來封裝NSLayoutConstraint,通過這種方式編寫Auto Layout布局代碼更加易讀和簡潔。
使用Masonry的MASConstraintMaker來表達相同constraint

  1. UIEdgeInsets padding = UIEdgeInsetsMake(10101010); 
  2.  
  3. [view1 mas_makeConstraints:^(MASConstraintMaker *make) { 
  4.     make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler 
  5.     make.left.equalTo(superview.mas_left).with.offset(padding.left); 
  6.     make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom); 
  7.     make.right.equalTo(superview.mas_right).with.offset(-padding.right); 
  8. }]; 

甚至可以更短

  1. [view1 mas_makeConstraints:^(MASConstraintMaker *make) { 
  2.     make.edges.equalTo(superview).with.insets(padding); 
  3. }]; 

#p#

如何使用

使用Masonry創(chuàng)建constraint來定義布局的方式有三種:mas_makeConstraints,mas_updateConstraints,mas_remakeConstraints。

1. mas_makeConstraints

使用mas_makeConstraints創(chuàng)建constraint后,你可以使用局部變量或?qū)傩詠肀4嬉员阆麓我盟蝗绻麆?chuàng)建多個constraints,你可以采用數(shù)組來保存它們。

  1. // in public/private interface 
  2. @property (nonatomic, strong) MASConstraint *topConstraint; 
  3.  
  4. ... 
  5.  
  6. // when making constraints 
  7. [view1 mas_makeConstraints:^(MASConstraintMaker *make) { 
  8.     self.topConstraint = make.top.equalTo(superview.mas_top).with.offset(padding.top); 
  9.     make.left.equalTo(superview.mas_left).with.offset(padding.left); 
  10. }]; 
  11.  
  12. ... 
  13. // then later you can call 
  14. [self.topConstraint uninstall]; 

2. mas_updateConstraints

有時你需要更新constraint(例如,動畫和調(diào)試)而不是創(chuàng)建固定constraint,可以使用mas_updateConstraints方法

  1. // this is Apple's recommended place for adding/updating constraints 
  2. // this method can get called multiple times in response to setNeedsUpdateConstraints 
  3. // which can be called by UIKit internally or in your code if you need to trigger an update to your constraints 
  4. - (void)updateConstraints { 
  5.     [self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) { 
  6.         make.center.equalTo(self); 
  7.         make.width.equalTo(@(self.buttonSize.width)).priorityLow(); 
  8.         make.height.equalTo(@(self.buttonSize.height)).priorityLow(); 
  9.         make.width.lessThanOrEqualTo(self); 
  10.         make.height.lessThanOrEqualTo(self); 
  11.     }]; 
  12.  
  13.     //according to apple super should be called at end of method 
  14.     [super updateConstraints]; 

3. mas_remakeConstraints

mas_remakeConstraints與mas_updateConstraints比較相似,都是更新constraint。不過,mas_remakeConstraints是刪除之前constraint,然后再添加新的constraint(適用于移動動畫);而mas_updateConstraints只是更新constraint的值。

  1. - (void)changeButtonPosition { 
  2.     [self.button mas_remakeConstraints:^(MASConstraintMaker *make) { 
  3.         make.size.equalTo(self.buttonSize); 
  4.  
  5.         if (topLeft) { 
  6.             make.top.and.left.offset(10); 
  7.         } else { 
  8.             make.bottom.and.right.offset(-10); 
  9.         } 
  10.     }]; 

想了解以上三個代碼片段的更多細節(jié),可以下載Masonry iOS Examples工程查閱。

Classy

Classy簡介和特性

Classy是一個能與UIKit無縫結合stylesheet(樣式)系統(tǒng)。它借鑒CSS的思想,但引入新的語法和命名規(guī)則。

靈活內(nèi)嵌的語法

{ } : ; 這些語法符號是可選的,你可以選擇適合自己的風格來表達stylesheet。

你可以使用{ } : ; 來限定stylesheet

  1. $main-color = #e1e1e1; 
  2.  
  3. MYCustomView { 
  4.   background-color: $main-color; 
  5.   title-insets: 510510
  6.   > UIProgressView.tinted { 
  7.     progress-tint-color: black; 
  8.     track-tint-color: yellow; 
  9.   } 
  10.  
  11. ^UIButton.warning, UIView.warning ^UIButton { 
  12.   title-color[state:highlighted]: #e3e3e3; 

或者你使用空格來限定stylesheet

  1. $main-color = #e1e1e1 
  2.  
  3. MYCustomView  
  4.   background-color $main-color 
  5.   title-insets 510510 
  6.   > UIProgressView.tinted  
  7.     progress-tint-color black 
  8.     track-tint-color yellow 
  9.  
  10. ^UIButton.warning, UIView.warning ^UIButton  
  11.   title-color[state:highlighted] #e3e3e3 

默認樣式

Classy在應用程序Bundle默認查找文件名為stylesheet.cas的樣式文件。如果你采用這個文件名,你可以不用做任何東西就能加載樣式文件。
但如果你想指定其他file path(樣式文件名),你可以創(chuàng)建[CASStyler defaultStyler]

  1. [CASStyler defaultStyler].filePath = [[NSBundle mainBundle] pathForResource:@"myStyles.cas" ofType:nil]; 

如果你還想當發(fā)生錯誤時,獲取錯誤信息以便于調(diào)試,可以使用-(void)setFilePath:error:

  1. NSError *error = nil; 
  2. NSString filePath = [[NSBundle mainBundle] pathForResource:@"myStyles.cas" ofType:nil]; 
  3. [[CASStyler defaultStyler] setFilePath:filePath error:&error]; 

如果你是使用Storyboard/Xib組織UI界面,那就需要在main.m的int main(int argc, char * argv[])方法設置 filePath,這樣可以確保在創(chuàng)建UIWindow之前加載stylesheet。否則(采用手寫UI代碼),你在 AppDelegate.m的- (BOOL)application:didFinishLaunchingWithOptions:方法設置filePath

Live Reload

Live Reload是實時顯示編寫UI代碼效果的關鍵特性,它能夠?qū)崟r檢查stylesheet文件變化,無需重新編譯、構建和運行模擬器,從而極大提高開發(fā)速度。
為了啟用Live Reload,你需要指定stylesheet路徑,并且只運行在模擬器上。

  1. #if TARGET_IPHONE_SIMULATOR 
  2.     NSString *absoluteFilePath = CASAbsoluteFilePath(@"../Styles/stylesheet.cas"); 
  3.     [CASStyler defaultStyler].watchFilePath = absoluteFilePath; 
  4. #endif 

Selectors

Style Selectors是指定哪個view使用哪種樣式的方式。主要有三種方法來指定目標view:

  1. Object Class
  2. View Hierarchy
  3. Style Class

你可以混合使用三種方法,例子如下:

  1. /* match views 
  2.  * where class is UIButton or UIButton subclass 
  3.  * and styleClass is "large" 
  4.  * and superview class is UITabBar 
  5.  */ 
  6.  
  7. UITabBar > ^UIButton.large { } 

想了解具體如何使用,請查閱官網(wǎng)Selectors章節(jié)

為了避免與Objective-C的message selectors混淆,術語style selectors表示Classy stylesheets的selectors

Properties

Classy支持所有UIAppearance的屬性和方法,也支持與UIAppearance無關的很多屬性。Classy使用與UIKit相同屬性命名,所以你不必考慮如何將style property映射到Objective-C的property。
UIPageControl類的屬性如下:

  1. @property (nonatomic,retain) UIColor *pageIndicatorTintColor; 
  2. @property (nonatomic,retain) UIColor *currentPageIndicatorTintColor; 

style property的名字采用與objective-c一樣的名字

  1. UIPageControl { 
  2.   pageIndicatorTintColor black 
  3.   currentPageIndicatorTintColor purple 

style property的命名規(guī)則采用kebab case

  1. UIPageControl { 
  2.   page-indicator-tint-color black 
  3.   current-page-indicator-tint-color purple 

想了解具體如何使用,請查閱官網(wǎng)Properties章節(jié)

Keep it DRY(Don't Repeat Yourself)

在編程中一個很重要的原則就是避免重復,這不僅可以大量減少重復代碼,并且使得代碼更加容易復用和維護。Classy提供三種方式避免代碼重復:grouping,nesting,variables

Grouping

如果有兩個以上的style selectors共用相同的屬性時

  1. UISlider.info { 
  2.   minimum-track-tint-color black 
  3.   maximum-track-tint-color purple 
  4.  
  5. UISlider.error { 
  6.   minimum-track-tint-color black 
  7.   maximum-track-tint-color purple 
  8.   thumb-tint-color red 

我們可以提取相同的屬性到分組style selector中

  1. UISlider.info, UISlider.error { 
  2.   minimum-track-tint-color black 
  3.   maximum-track-tint-color purple 
  4.  
  5. UISlider.error { 
  6.   thumb-tint-color red 

#p#

Nesting

如果兩個以上style selectors共用相同的view hierarchy時

  1. UICollectionView { 
  2.   background-color #a2a2a2 
  3.  
  4. UICollectionView > UICollectionViewCell { 
  5.   clips-to-bounds NO 
  6.  
  7. UICollectionView > UICollectionViewCell UILabel { 
  8.   text-color purple 
  9.  
  10. UICollectionView > UICollectionViewCell UILabel.title { 
  11.   font 20 

我們通過nesting方式將view hierarchies表達成這樣方式

  1. UICollectionView { 
  2.   background-color #a2a2a2 
  3.  
  4.   > UICollectionViewCell { 
  5.     clips-to-bounds NO 
  6.  
  7.     UILabel { 
  8.       text-color purple 
  9.  
  10.       &.title { 
  11.         font 20 
  12.       } 
  13.     } 
  14.   } 

Variables

Classy讓你通過定義variables來將多個相同的style property值存儲以便共享。Variable命名規(guī)則如下:

  • 必須以大小寫字母或$符號開頭
  • 可以包含_,-或任何字母數(shù)字

    1. // prefix with ' $ ' to help distinguish variables 
    2. $brand-color = #e1e1e1 
    3.  
    4. // OR not 
    5. insets = 510510 
    6.  
    7. UIButton { 
    8.   background-color $brand-color 
    9.   contentEdgeInsets insets 
    10.   background-image[state:selected] bg_button insets 

    ***官方還提供一個實例來解釋具體如何使用:Custom Views Example

ClassyLiveLayout

ClassyLiveLayout通過結合Classy stylesheets與Masonry一起使用,能夠在運行的模擬器中微調(diào)Auto Layout約束實時顯示效果的工具。

ClassyLiveLayout一個核心category:UIView+ClassyLayoutProperties,在UIView定義以下屬性:

  1. @property(nonatomic, assign) UIEdgeInsets cas_margin; 
  2. @property(nonatomic, assign) CGSize cas_size; 
  3.  
  4. // shorthand properties for setting only a single constant value 
  5. @property(nonatomic, assign) CGFloat cas_sizeWidth; 
  6. @property(nonatomic, assign) CGFloat cas_sizeHeight; 
  7.  
  8. @property(nonatomic, assign) CGFloat cas_marginTop; 
  9. @property(nonatomic, assign) CGFloat cas_marginLeft; 
  10. @property(nonatomic, assign) CGFloat cas_marginBottom; 
  11. @property(nonatomic, assign) CGFloat cas_marginRight; 

cas_margin和cas_size分別表示UI元素的位置和大小,而其余的屬性都是對兩個屬性進一步細分。我們可以從stylesheets中訪問style properties來定義constraints布局,做到將數(shù)據(jù)與代碼分離,有利于修改和復用代碼。

  1. UIView.blue-box { 
  2.     cas_size: 80 100 
  3.     cas_margin-top: 60 
  4.     cas_margin-left: 50 
  5.  
  6. UIView.red-box { 
  7.     cas_size-width: 120 
  8.     cas_margin-left: 20 

我們可以在updateConstraints或updateViewConstrains定義布局時引用style properties

  1. - (void)updateViewConstraints { 
  2.   [super updateViewConstraints]; 
  3.  
  4.   [_blueBoxView mas_updateConstraints:^(MASConstraintMaker *make) { 
  5.       make.width.equalTo(@(_blueBoxView.cas_size.width)); 
  6.       make.height.equalTo(@(_blueBoxView.cas_size.height)); 
  7.       make.top.equalTo(@(_blueBoxView.cas_margin.top)); 
  8.       make.left.equalTo(@(_blueBoxView.cas_margin.left)); 
  9.   }]; 
  10.  
  11.   [_redBoxView mas_updateConstraints:^(MASConstraintMaker *make) { 
  12.       make.width.equalTo(@(_redBoxView.cas_size.width)); 
  13.       make.height.equalTo(_blueBoxView); 
  14.       make.top.equalTo(_blueBoxView); 
  15.       make.left.equalTo(_blueBoxView.mas_right).with.offset(_redBoxView.cas_margin.left); 
  16.   }]; 

當定義view layouts時,將Auto Layout的constraints都放在stylesheets中實時加載(Live reload)。如果你修改constraints,無需重新編譯、構建和運行模擬器便能實時看到修改后的效果。

示例工程

配置工程

由于需要引用Masonry,Classy和ClassyLiveLayout,Podfile配置如下:

  1. pod 'Masonry''~> 0.6.1' 
  2. pod 'Classy''~> 0.2.4' 
  3. pod 'ClassyLiveLayout''~> 0.6.0' 

編寫代碼

1. 添加stylesheet.cas文件到工程

當安裝好Masonry,Classy和ClassyLiveLayout后,***次運行項目會出現(xiàn)沒有stylesheet.cas文件錯誤:

No stylesheet.cas file error.png

No stylesheet.cas file error.png

 

只要向工程添加空的stylesheet.cas文件即可。

Create stylesheet.cas file.png

Create stylesheet.cas file.png

 

2. 創(chuàng)建LiveView類,該類繼承SHPAbstractView。

Create LiveView inherit SHPAbstractView.png

Create LiveView inherit SHPAbstractView.png

 

在ViewController創(chuàng)建LiveView對象,然后被self.view引用。

Setup root view in ViewController.png

Setup root view in ViewController.png

 

當編譯運行時,在SHPAbstractView.h由于找不到UIView出現(xiàn)編譯錯誤。

SHPAbstractView Compile error.png

SHPAbstractView Compile error.png

 

#p#

只需引入UIKit便可以解決,但運行一下應用程序,出現(xiàn)一下錯誤:

Must override methods.png

Must override methods.png

 

主要原因是任何自定義UIView繼承SHPAbstractView都需要override兩個方法:- (void)addSubviews和- (void)defineLayout,我們可以查看SHPAbstractView的源碼可知:

SHPAbstractView Source Code .png

SHPAbstractView Source Code .png

 

所以只要在LiveView.m文件覆蓋兩個方法即可

  1. #pragma mark - Add subviews and define layout 
  2. - (void)addSubviews 
  3.  
  4. - (void)defineLayout 

3. LiveView類設計

LiveView主要由包含redBoxView和blueBoxView兩個屬性,redBoxView表示紅色方塊,blueBoxView表示藍色方塊。

  1. #import "SHPAbstractView.h" 
  2.  
  3. @interface LiveView : SHPAbstractView 
  4.  
  5. @property (strong, nonatomic) UIView *redBoxView; 
  6. @property (strong, nonatomic) UIView *blueBoxView; 
  7.  
  8. @end 

4. LiveView類實現(xiàn)

由于SHPAbstractView類如何初始化View已經(jīng)做了處理,暴露兩個接口- (void)addSubviews和-(void)defineLayout分別處理構建view hierarchy和定義布局,子類只要覆蓋SHPAbstractView這兩個方法就可以創(chuàng)建LiveView了。
但是我們將Auto Layout的constraints都放在stylesheets中實時加載(Live reload),即放在本工程的stylesheet.cas文件,將布局數(shù)據(jù)和布局代碼分離。

  1. UIView.redBox { 
  2.     cas_marginTop 50 
  3.     cas_marginLeft 20 
  4.  
  5.     cas_size 100 100 
  6.  
  7. UIView.blueBox { 
  8.     cas_marginTop 50 
  9.     cas_marginRight -20 
  10.  
  11.     cas_size 100 100 

有了constraints數(shù)據(jù)后,便可以在代碼布局:

  1. @implementation LiveView 
  2.  
  3. #pragma mark - Add subviews and define layout 
  4. - (void)addSubviews 
  5.     self.backgroundColor = [UIColor whiteColor]; 
  6.     [self addSubview:self.redBoxView]; 
  7.     [self addSubview:self.blueBoxView]; 
  8.  
  9. - (void)defineLayout 
  10.     [self.redBoxView mas_updateConstraints:^(MASConstraintMaker* make){ 
  11.         make.top.equalTo(@(self.redBoxView.cas_marginTop)); 
  12.         make.left.equalTo(@(self.redBoxView.cas_marginLeft)); 
  13.         make.width.equalTo(@(self.redBoxView.cas_sizeWidth)); 
  14.         make.height.equalTo(@(self.redBoxView.cas_sizeHeight)); 
  15.     }]; 
  16.  
  17.     [self.blueBoxView mas_updateConstraints:^(MASConstraintMaker *make){ 
  18.         make.top.equalTo(@(self.blueBoxView.cas_marginTop)); 
  19.         make.right.equalTo(@(self.blueBoxView.cas_marginRight)); 
  20.         make.width.equalTo(@(self.blueBoxView.cas_sizeWidth)); 
  21.         make.height.equalTo(@(self.blueBoxView.cas_sizeHeight)); 
  22.     }]; 
  23.  
  24. #pragma mark - Lazy initialization 
  25. - (UIView*)redBoxView 
  26.     if (!_redBoxView) { 
  27.         _redBoxView = [UIView new]; 
  28.         _redBoxView.cas_styleClass = @"redBox"
  29.         _redBoxView.backgroundColor = [UIColor redColor]; 
  30.     } 
  31.  
  32.     return _redBoxView; 
  33.  
  34. - (UIView*)blueBoxView 
  35.     if (!_blueBoxView) { 
  36.         _blueBoxView = [UIView new]; 
  37.         _blueBoxView.cas_styleClass = @"blueBox"
  38.         _blueBoxView.backgroundColor = [UIColor blueColor]; 
  39.     } 
  40.  
  41.     return _blueBoxView; 

5. 模擬器支持Live Reload

為了啟用Live Reload,你需要指定stylesheet路徑,并且只運行在模擬器上。

Support Live Reload.png

Support Live Reload.png

 

此時效果:

Live Change.gif

 

#p#

6. 分離樣式文件

由于有網(wǎng)友提出這樣一個問題:如果所有view的樣式都放在同一個stylesheet.cas文件,會讓stylesheet.cas文件繁雜,并且當多個人協(xié)同開發(fā)時,不易于合并代碼,所以有必要將樣式文件分離到多個文件中。

  1. 創(chuàng)建variable.cas文件,并將redBox對應UIView的樣式放在variable.cas文件中。

    variable.cas file.png

    variable.cas file.png

     

  2. 在stylesheet.cas樣式文件使用@import指令引用variable.cas文件

stylesheet.cas file.png

stylesheet.cas file.png

 

***效果

Live Change 1.gif

Live Change 2.gif

 

示例代碼存放地址:LiveAutoLayout

總結

之前手寫UI代碼每次更改一般都要重新編譯、構建和運行模擬器才能看到效果,但結合使用Masonry,Classy和ClassLiveLayout之后,告別這個費時過程,極大地提高開發(fā)速度;不僅如此,我們將Auto Layout的constraints都放在stylesheets中實時加載(Live reload),將布局數(shù)據(jù)和布局代碼分離,使得代碼更加復用和維護。Classy還提供三種避免重復方法:Grouping, Nestting和Variable,盡可能復用樣式數(shù)據(jù)。
這是本人***次編寫技術博客,可能有很多錯誤和漏洞,希望大家多多指點,也希望這篇文章能夠幫助到大家。

責任編輯:倪明 來源: 簡書
相關推薦

2024-03-15 12:48:50

攜程AI

2012-04-24 23:31:41

iOS

2011-08-22 16:45:58

Windows PhoiOS

2021-01-19 12:16:10

CSS前端UI

2010-09-09 11:16:06

CSS交互

2022-09-27 14:32:12

iOSiOS 16蘋果

2010-04-29 17:22:42

UNIX系統(tǒng)

2009-07-10 13:20:37

Swing容器組件

2011-06-28 17:21:50

QT UI designer

2021-06-03 07:45:25

Rust Git 終端 UI

2009-06-25 14:53:35

自定義UI組件JSF框架

2020-03-17 14:26:18

iOS 14iPhone 9 Pl蘋果

2012-09-10 10:31:31

IBMdw

2012-07-02 12:13:32

明基投影機

2011-07-08 15:08:16

iPhone 圖片

2012-09-06 11:18:17

IBMdw

2019-11-08 09:20:57

代碼開發(fā)工具

2010-01-14 14:40:21

C++代碼

2012-07-11 10:51:37

編程

2012-03-15 13:36:51

云計算JavaSpring框架
點贊
收藏

51CTO技術棧公眾號

欧美一区永久视频免费观看| 国产亚洲综合av| 欧美精品电影在线| 国产精品1000部啪视频| 亚洲成人激情社区| 国产精品午夜电影| 国产伦理久久久| 成人黄色三级视频| 一区免费视频| 国产亚洲a∨片在线观看| 超碰成人在线播放| 男人av在线播放| 国产精品传媒入口麻豆| 国产精品久久久久久久久婷婷| 岛国av中文字幕| 久久久久国产精品| 亚洲美女性视频| 一级黄色片在线免费观看| 亚洲人体视频| 亚洲精品国久久99热| 欧美日韩精品免费观看| 性一交一乱一伧老太| 亚洲欧美视频一区二区三区| 欧美成人精品在线观看| 99久久99久久精品免费看小说. | 91精品免费视频| 九九热在线视频播放| 一区二区国产在线| 国产一级揄自揄精品视频| 国产精品日日摸夜夜爽| 岛国一区二区| 欧美日韩中文字幕在线| 天天想你在线观看完整版电影免费| 免费一级在线观看| 成人精品国产免费网站| 91日韩在线视频| 日本中文字幕在线观看视频| 国产欧美在线| 欧美韩日一区二区| 国产精品白丝喷水在线观看| jizzjizz欧美69巨大| 日韩久久免费视频| 中文字幕在线视频播放| 午夜视频一区二区在线观看| 欧美日韩视频在线一区二区| 欧美成人免费高清视频| 久热在线观看视频| 亚洲成人福利片| 免费看污污视频| 三区四区在线视频| 中文字幕乱码久久午夜不卡| 日本一区精品| 免费在线超碰| 久久精品亚洲麻豆av一区二区 | 国产美女视频免费看| 韩日精品一区| 欧美日韩国产一区二区三区地区| 成年人视频在线免费| 亚洲欧洲日本韩国| 色婷婷亚洲一区二区三区| 色综合久久久久无码专区| 黄色的视频在线观看| 亚洲一二三区视频在线观看| 国产一区二区四区| h片在线观看视频免费免费| 一区二区三区美女| 成年人网站国产| av资源在线播放| 精品久久中文字幕久久av| 免费看又黄又无码的网站| 性欧美又大又长又硬| 精品欧美国产一区二区三区| 国产午夜福利在线播放| 欧美18av| 欧美老年两性高潮| 一级黄色大片儿| av男人一区| 欧美成人女星排名| 精品黑人一区二区三区观看时间| 日韩精品免费一区二区夜夜嗨 | bestiality新另类大全| 一区二区三区免费观看| 免费看又黄又无码的网站| 亚洲成人av观看| 这里是久久伊人| 中国免费黄色片| 国产精品羞羞答答在线观看| 丝袜亚洲欧美日韩综合| 亚洲一区二区三区四区视频| 午夜免费激情视频| 亚洲高清毛片| 日韩免费精品视频| 国产精品玖玖玖| av网站免费线看精品| 日韩欧美手机在线| 午夜羞羞小视频在线观看| 欧美午夜激情小视频| 国产福利在线免费| xxxxxhd亚洲人hd| 国产亚洲精品综合一区91| 欧美日韩国产精品综合| 亚洲尤物精选| 91人人爽人人爽人人精88v| 亚州男人的天堂| 国产精品视频一二三区| 波多野结衣av一区二区全免费观看| 偷拍自拍在线看| 欧美一区欧美二区| 亚洲午夜久久久久久久久红桃| 99久久九九| 77777亚洲午夜久久多人| 91无套直看片红桃| av电影在线观看一区| 伊人久久大香线蕉精品 | 2019最新中文字幕| 国产美女主播在线观看| 91麻豆蜜桃一区二区三区| 干日本少妇视频| 电影亚洲精品噜噜在线观看| 欧美v日韩v国产v| 成人欧美一区二区三区黑人一 | 亚洲一区欧美一区| 91高清国产视频| 亚洲伊人春色| 久久全国免费视频| 国产成人精品亚洲精品色欲| 国产亚洲成av人在线观看导航 | 免费成人美女在线观看.| 国产亚洲一区二区三区在线播放 | 日本中文字幕影院| 国内成人自拍| 51色欧美片视频在线观看| 性欧美videos另类hd| 国产精品初高中害羞小美女文| 5月婷婷6月丁香| eeuss国产一区二区三区四区| 日韩在线精品视频| 中文字幕av久久爽| 久久久久九九视频| 5月婷婷6月丁香| 极品束缚调教一区二区网站 | 国产伦精品一区二区三区免费迷 | 3d动漫精品啪啪1区2区免费| 青青草自拍偷拍| 日本vs亚洲vs韩国一区三区| 日韩精品一区二区三区丰满| 亚洲日本天堂| 国产亚洲人成网站在线观看| 久久影视中文字幕| 日本一区二区三区dvd视频在线| 人妻少妇被粗大爽9797pw| 极品束缚调教一区二区网站| 97精品视频在线| 香港一级纯黄大片| 精品日韩中文字幕| 无码人妻aⅴ一区二区三区| 中文欧美日韩| 欧美日韩一区二区视频在线| 人人鲁人人莫人人爱精品| 一区二区在线免费视频| 中文字幕一二区| 一区视频在线播放| 亚洲男人天堂2021| 国内在线观看一区二区三区| 电影午夜精品一区二区三区| free性m.freesex欧美| 国产女人18毛片18精品| 一区二区国产视频| 亚洲调教欧美在线| 久久久国产精品一区二区中文| 欧美一区二区在线| 91成人小视频| 欧美激情欧美激情| 三级理论午夜在线观看| 在线观看日韩高清av| 日本成人免费在线观看| 国产69精品久久777的优势| 久草视频国产在线| 精品国产一区二区三区小蝌蚪 | 免费国产羞羞网站视频| 婷婷丁香激情综合| 国产精品成人无码免费| 精品一区二区三区在线播放视频| 男人草女人视频| 日韩人体视频| 成人黄在线观看| 九色91在线| 亚洲日本aⅴ片在线观看香蕉| 在线黄色av网站| 亚洲国产欧美一区二区三区丁香婷| 香港三日本8a三级少妇三级99| 日韩国产欧美一区二区三区| 国产女人18毛片| 西瓜成人精品人成网站| 91美女片黄在线观| 性欧美xxx69hd高清| 久久精品中文字幕免费mv| 手机av免费在线观看| 欧美日韩一区高清| 免费毛片一区二区三区| 国产精品系列在线| 国产视频久久久久久| 久久国产福利国产秒拍| 欧美视频在线播放一区| 天堂美国久久| 欧美三级华人主播| 91麻豆精品激情在线观看最新| 国产999视频| 2020国产在线| 久久精品久久久久久| 男女视频在线观看免费| 欧美r级电影在线观看| 中文在线观看免费高清| 激情成人中文字幕| 欧美日韩在线观看成人| 国产精品青草久久| 少妇特黄一区二区三区| 丰满亚洲少妇av| 岛国毛片在线播放| 视频一区二区国产| 亚洲国产成人精品无码区99| 一区二区蜜桃| 影音先锋欧美资源| 精品国产乱码久久久久久果冻传媒 | 中文字幕在线观看日韩| 免费在线一级视频| 亚洲精品国产精品国产自| 高潮毛片7777777毛片| 欧美一区二区三区四区视频| 一卡二卡在线视频| 欧美网站一区二区| 自拍偷拍色综合| 在线免费亚洲电影| 国产又粗又爽视频| 精品久久久中文| 日韩 欧美 中文| 欧美日韩亚洲一区二| 91蜜桃视频在线观看| 亚洲一区二区三区四区五区黄| 成年人午夜剧场| 亚洲综合一区在线| 久久久久久免费观看| 一片黄亚洲嫩模| 国产第一页在线播放| 亚洲福利视频三区| 国产精品9191| 丰满岳妇乱一区二区三区| 在线观看黄网站| 日韩欧美在线观看| 亚洲高清在线看| 欧美日韩国产一二三| 国产精品嫩草影院桃色| 欧美一二三四区在线| 亚洲精品中文字幕成人片 | 黄色av网站在线看| 亚洲午夜色婷婷在线| 高清性色生活片在线观看| 日韩免费高清视频| а√天堂资源在线| 4438x成人网最大色成网站| 国产原创中文av| 7777精品伊人久久久大香线蕉的| 91麻豆成人精品国产免费网站| 欧美色视频一区| 在线观看免费中文字幕| 日韩免费看网站| 亚洲高清视频网站| 精品国精品自拍自在线| 天堂а在线中文在线无限看推荐| 国产视频精品久久久| 日本免费一区二区三区最新| 国产一区二区三区在线观看视频| 国内精品在线视频| 在线观看国产精品淫| caoporn97在线视频| 欧美激情xxxxx| 韩国成人二区| 国产区精品在线观看| 国产一区二区三区国产精品| 91欧美激情另类亚洲| 日韩欧美中文字幕电影| 日本一区二区三区视频在线播放| 欧美日中文字幕| 日韩一级特黄毛片| 国产欧美在线| 天美星空大象mv在线观看视频| 国产一区二区在线视频| 好吊操视频这里只有精品| 91亚洲资源网| 日本黄区免费视频观看 | 久久精品亚洲无码| 一本大道久久a久久综合婷婷| 中文字幕 自拍偷拍| 亚洲第一中文字幕在线观看| 美女欧美视频在线观看免费 | 狼狼综合久久久久综合网| 国产日产精品一区二区三区四区的观看方式 | 久久久精品久久| 高清精品在线| 国产精品第二页| 这里视频有精品| 日韩免费电影一区二区| 精品成人一区| 第一区免费在线观看| 99久久国产免费看| 成人免费精品动漫网站| 欧美色播在线播放| 97超视频在线观看| 亚洲色图校园春色| 少女频道在线观看高清| 国产不卡一区二区在线播放| 永久免费精品视频| 欧美亚洲爱爱另类综合| 91综合在线| 女性隐私黄www网站视频| 国产一区二区三区观看| 国产肥白大熟妇bbbb视频| 夜夜亚洲天天久久| 中文字幕一区二区久久人妻| 亚洲精品中文字| 美女尤物在线视频| 国产精品亚洲视频在线观看| 亚洲高清极品| 人人妻人人澡人人爽欧美一区| 欧美一区=区| 你懂得在线视频| 一区二区三区在线免费观看 | 日韩精品一区二区三区视频播放| 免费在线超碰| 欧美在线视频一区| 大陆精大陆国产国语精品| 97超碰人人爱| 九一九一国产精品| 欧美福利第一页| 亚洲国产欧美在线| 99视频在线观看免费| 亚洲午夜av久久乱码| 黄色激情在线播放| 国产精品久久亚洲7777| 亚洲破处大片| 精品人妻人人做人人爽夜夜爽| 国产精品久久久久久久第一福利| 在线观看免费国产视频| 亚洲国产日韩精品在线| 日韩影视在线| 国产乱码一区| 亚洲黄色大片| 无码av免费精品一区二区三区| 洋洋成人永久网站入口| 国产手机av在线| 久久99久国产精品黄毛片入口| 欧美特黄不卡| 超薄肉色丝袜足j调教99| 丁香天五香天堂综合| 欧美做爰爽爽爽爽爽爽| 欧美男男青年gay1069videost| 川上优的av在线一区二区| 日韩av电影在线网| 成人久久综合| 一级黄色特级片| 中文字幕欧美激情一区| 91肉色超薄丝袜脚交一区二区| 久久精品国产亚洲精品| 91精品国产自产在线丝袜啪| 91网站在线观看免费| 91麻豆免费视频| 欧美亚洲另类小说| 亚洲天堂影视av| 国产精品一区二区精品视频观看 | 四季av日韩精品一区| 欧美亚洲在线视频| 国产一区二区三区四区二区| 十八禁视频网站在线观看| 国产精品日韩精品欧美在线| 伊人久久一区二区| 欧美成人午夜激情| 国产成人一二| 久久久久国产精品熟女影院| 国产欧美一区二区精品忘忧草 | 777奇米四色成人影色区| 成人影院www在线观看| 亚洲va久久久噜噜噜久久天堂| 欧美久久一区| 欧美偷拍一区二区三区| 精品视频一区三区九区| 麻豆网站在线免费观看| 国产精品白丝jk白祙| 美女精品一区| 青青草原在线免费观看| 亚洲成人在线视频播放| a国产在线视频| 综合色婷婷一区二区亚洲欧美国产| 国产成人在线视频免费播放| 亚洲免费黄色网址| 久久精品中文字幕| 亚洲精品无吗| 真实乱偷全部视频| 午夜视频在线观看一区二区| 99reav在线| 激情久久av|