此篇文章將要介紹IOS下的界面布局利器的相關介紹,具體實例請看下文
Swift:TangramKit: https://github.com/youngsoft/TangramKit OC:MyLayout: https://github.com/youngsoft/MyLinearLayout 簡介MyLayout是一套IOS界面視圖布局框架。其內核是基於對UIView的layoutSubviews方法的重載以及對子視圖的bounds和center屬性的設置而實現的。MyLayout功能強大而且簡單易用,它集成了iOS Autolayout和Size Classes、Android的5大布局體系、HTML/CSS的浮動定位技術以及flex-box和bootstrap框架等市面上主流的平台的界面布局功能,同時提供了一套非常簡單和完備的多屏幕尺寸適配的解決方案。MyLayout還提供了Swift版本TangramKit
MyLayout的優勢 MyLayout的實現內核是基於frame的設置,而不是對AutoLayout的封裝。因此在使用上不會受到任何操作系統版本的限制。 有文章表明用frame進行布局的性能要高於用AutoLayout進行布局的性能,尤其是當界面內視圖數量增加時效果更加明顯。 AutoLayout的思想是通過視圖之間的約束依賴來完成布局,但是約束依賴的結果是造成視圖之間的耦合性高而增大了界面更新的成本。而MyLayout則除了提供約束依賴外,還提供了根據視圖添加順序自動建立約束的功能,從而減少了這種顯示依賴關系建立的問題,最終的結果是簡化了布局的代碼量,以及減少了布局更新時的代碼修改量。 AutoLayout只是一種相對約束的布局,而MyLayout除了同時提供具有和AutoLayout相同能力的相對布局外、還提供了線性布局、框架布局、表格布局、流式布局、浮動布局、路徑布局7大布局體系,你完全可以根據你的界面需求來選擇一種最簡易的布局容器來實現你的功能,同時MyLayout還支持Size classes的機制,以及提供了一些實現屏幕尺寸完美適配的方法。 MyLayout主要是一種通過代碼進行布局的解決方案,但是框架一樣可以支持和XIB以及SB結合布局的方式。並提供了視圖隱藏和顯示時會自動激發布局、布局視圖的高度自適應(UITableviewCell動態高度)、標簽雲實現、左右內容寬度自適應、按比例分配尺寸和間距、整體停靠控制等等各種強大的功能。 AutoLayout和frame布局的性能比較參考的文章地址: http://floriankugler.com/2013/04/22/auto-layout-performance-on-ios/
應用場景舉例下面一個應用場景:
有一個容器視圖S的寬度是100而高度則是由四個從上到下依次排列的子視圖A,B,C,D的高度總和。 視圖A的左邊距占用父視圖寬度的20%,而右邊距則占用父視圖寬度的30%,高度則等於自身的寬度。 視圖B的左邊距是40,寬度則占用父視圖的剩余寬度,高度是40。 視圖C的寬度占用父視圖的所有寬度,高度是40。 視圖D的右邊距是20,寬度是父視圖寬度的50%,高度是40。最終的效果圖如下:
MyLinearLayout *S = [MyLinearLayout linearLayoutWithOrientation:MyLayoutViewOrientation_Vert]; S.subviewMargin = 10; S.myWidth = 100; UIView *A = UIView.new; A.leftPos.equalTo(@0.2); A.rightPos.equalTo(@0.3); A.heightDime.equalTo(A.widthDime); [S addSubview:A]; UIView *B = UIView.new; B.leftPos.equalTo(@40); B.widthDime.equalTo(@60); B.heightDime.equalTo(@40); [S addSubview:B]; UIView *C = UIView.new; C.widthDime.equalTo(S.widthDime); C.heightDime.equalTo(@40); [S addSubview:C]; UIView *D = UIView.new; D.rightPos.equalTo(@20); D.widthDime.equalTo(S.widthDime).multiply(0.5); D.heightDime.equalTo(@40); [S addSubview:D];系統結構 布局位置類MyLayoutPos
MyLayoutPos類是用來描述一個視圖所在的位置的類。UIView中擴展出了leftPos,topPos,bottomPos,rightPos,centerXPos,centerYPos這六個變量來實現視圖的定位操作。您可以用這些變量的equalTo
方法來設置視圖之間的邊距和間距。 equalTo
方法可以設置NSNumber, MyLayoutPos, NSArray<MyLayoutPos*>這幾種值,分別用於不同的場景。同時系統提供了6個簡單的變量myLeftMargin, myTopMargin, myBottomMargin, myRightMargin, myCenterXOffset, mYCenterYOffset來設置NSNumber類型的值,比如 A.leftPos.equalTo(@10); 等價於 A.myLeftMargin = 10;
.
MyLayoutSize類是用來描述一個視圖的尺寸的類。UIView中擴展出了widthDime,heightDime這兩個變量來實現視圖的寬度和高度尺寸的設置。您可以用其中的equalTo
方法來設置視圖的寬度和高度。equalTo
方法可以設置NSNumber, MyLayoutSize, NSArray<MyLayoutSize*>這幾種值,分別用於不同的場景。同時系統提供了2個簡單的變量myWidth,myHeight來設置NSNumber類型的值,比如A.widthDime.equalTo(@10); 等價於A.myWidth = 10;
.
等價於iOS的UIStackView和Android的LinearLayout布局。
線性布局是一種裡面的子視圖按添加的順序從上到下或者從左到右依次排列的單列(單行)布局視圖,因此裡面的子視圖是通過添加的順序建立約束和依賴關系的。 子視圖從上到下依次排列的線性布局視圖稱為垂直線性布局視圖,而子視圖從左到右依次排列的線性布局視圖則稱為水平線性布局。
示例代碼:
-(void)loadView { [super loadView]; MyLinearLayout *S = [MyLinearLayout linearLayoutWithOrientation:MyLayoutViewOrientation_Vert]; S.myWidth = 120; S.subviewMargin = 10; UIView *A = [UIView new]; A.myLeftMargin = A.myRightMargin = 5; A.myHeight = 40; [S addSubview:A]; UIView *B = [UIView new]; B.myLeftMargin = 20; B.myWidth = B.myHeight = 40; [S addSubview:B]; UIView *C = [UIView new]; C.myRightMargin = 40; C.myWidth = 50; C.myHeight = 40; [S addSubview:C]; UIView *D = [UIView new]; D.myLeftMargin = D.myRightMargin = 10; D.myHeight = 40; [S addSubview:D]; [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; A.backgroundColor = [UIColor greenColor]; B.backgroundColor = [UIColor blueColor]; C.backgroundColor = [UIColor orangeColor]; D.backgroundColor = [UIColor cyanColor]; }相對布局MyRelativeLayout
等價於iOS的AutoLayout 和 Android的RelativeLayout布局。
相對布局是一種裡面的子視圖通過相互之間的約束和依賴來進行布局和定位的布局視圖。相對布局裡面的子視圖的布局位置和添加的順序無關,而是通過設置子視圖的相對依賴關系來進行定位和布局的。
示例代碼:
-(void)loadView { [super loadView]; MyRelativeLayout *S = [MyRelativeLayout new]; S.widthDime.equalTo(@170); S.heightDime.equalTo(@280); UIView *A = [UIView new]; A.leftPos.equalTo(@20); A.topPos.equalTo(@20); A.widthDime.equalTo(@40); A.heightDime.equalTo(A.widthDime); [S addSubview:A]; UIView *B = [UIView new]; B.leftPos.equalTo(A.centerXPos); B.topPos.equalTo(A.bottomPos).offset(10); B.widthDime.equalTo(@60); B.heightDime.equalTo(A.heightDime); [S addSubview:B]; UIView *C = [UIView new]; C.leftPos.equalTo(B.rightPos).offset(10); C.bottomPos.equalTo(B.bottomPos); C.widthDime.equalTo(@40); C.heightDime.equalTo(B.heightDime).multiply(0.5); [S addSubview:C]; UIView *D = [UIView new]; D.bottomPos.equalTo(C.topPos).offset(10); D.rightPos.equalTo(@15); D.heightDime.equalTo(A.heightDime); D.widthDime.equalTo(D.heightDime); [S addSubview:D]; UIView *E = [UIView new]; E.centerYPos.equalTo(@0); E.centerXPos.equalTo(@0); E.heightDime.equalTo(@40); E.widthDime.equalTo(S.widthDime).add(-20); [S addSubview:E]; //.. F, G [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; A.backgroundColor = [UIColor greenColor]; B.backgroundColor = [UIColor blueColor]; C.backgroundColor = [UIColor orangeColor]; D.backgroundColor = [UIColor cyanColor]; E.backgroundColor = [UIColor magentaColor]; }框架布局MyFrameLayout
等價於Android的FrameLayout布局。
框架布局是一種裡面的子視圖停靠在父視圖特定方位並且可以重疊的布局視圖。框架布局裡面的子視圖的布局位置和添加的順序無關,只跟父視圖建立布局約束依賴關系。框架布局將垂直方向上分為上、中、下三個方位,而水平方向上則分為左、中、右三個方位,任何一個子視圖都只能定位在垂直方向和水平方向上的一個方位上。
示例代碼:
-(void)loadView { [super loadView]; MyFrameLayout *S = [MyFrameLayout new]; S.mySize = CGSizeMake(320,500); UIView *A = [UIView new]; A.mySize = CGSizeMake(40,40); [S addSubview:A]; UIView *B = [UIView new]; B.mySize = CGSizeMake(40,40); B.myRightMargin = 0; [S addSubview:B]; UIView *C = [UIView new]; C.mySize = CGSizeMake(40,40); C.myCenterYOffset = 0; [S addSubview:C]; UIView *D = [UIView new]; D.mySize = CGSizeMake(40,40); D.myCenterOffset = CGPointZero; [S addSubview:D]; //..E,F,G [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; A.backgroundColor = [UIColor greenColor]; B.backgroundColor = [UIColor blueColor]; C.backgroundColor = [UIColor orangeColor]; D.backgroundColor = [UIColor cyanColor]; }表格布局MyTableLayout
等價於Android的TableLayout布局和HTML的table元素。
表格布局是一種裡面的子視圖可以像表格一樣多行多列排列的布局視圖。子視圖添加到表格布局視圖前必須先要建立並添加行視圖,然後再將子視圖添加到行視圖裡面。如果行視圖在表格布局裡面是從上到下排列的則表格布局為垂直表格布局,垂直表格布局裡面的子視圖在行視圖裡面是從左到右排列的;如果行視圖在表格布局裡面是從左到右排列的則表格布局為水平表格布局,水平表格布局裡面的子視圖在行視圖裡面是從上到下排列的。
示例代碼:
-(void)loadView { [super loadView]; MyTableLayout *S = [MyTableLayout tableLayoutWithOrientation:MyLayoutViewOrientation_Vert]; S.wrapContentWidth = YES; S.rowSpacing = 10; S.colSpacing = 10; [S addRow:MTLSIZE_WRAPCONTENT colSize:MTLSIZE_WRAPCONTENT]; UIView *A = [UIView new]; A.mySize = CGSizeMake(50,40); [S addSubview:A]; UIView *B = [UIView new]; B.mySize = CGSizeMake(100,40); [S addSubview:B]; UIView *C = [UIView new]; C.mySize = CGSizeMake(30,40); [S addSubview:C]; [S addRow:MTLSIZE_WRAPCONTENT colSize:MTLSIZE_WRAPCONTENT]; UIView *D = [UIView new]; D.mySize = CGSizeMake(200,40); [S addSubview:D]; //...E,F [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; A.backgroundColor = [UIColor greenColor]; B.backgroundColor = [UIColor blueColor]; C.backgroundColor = [UIColor orangeColor]; D.backgroundColor = [UIColor cyanColor]; }流式布局MyFlowLayout
等價於CSS3的flex-box。
流式布局是一種裡面的子視圖按照添加的順序依次排列,當遇到某種約束限制後會另起一行再重新排列的多行展示的布局視圖。這裡的約束限制主要有數量約束限制和內容尺寸約束限制兩種,而換行的方向又分為垂直和水平方向,因此流式布局一共有垂直數量約束流式布局、垂直內容約束流式布局、水平數量約束流式布局、水平內容約束流式布局。流式布局主要應用於那些子視圖有規律排列的場景,在某種程度上可以作為UICollectionView的替代品。
示例代碼:
-(void)loadView { [super loadView]; MyFlowLayout *S = [MyFlowLayout flowLayoutWithOrientation:MyLayoutViewOrientation_Vert arrangedCount:4]; S.wrapContentHeight = YES; S.myWidth = 300; S.padding = UIEdgeInsetsMake(10, 10, 10, 10); S.gravity = MyMarginGravity_Horz_Fill; S.subviewMargin = 10; for (int i = 0; i < 10; i++) { UIView *A = [UIView new]; A.heightDime.equalTo(A.widthDime); [S addSubview:A]; A.backgroundColor = [UIColor greenColor]; } [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; }浮動布局MyFloatLayout
等價於css中的float定位。
浮動布局是一種裡面的子視圖按照約定的方向浮動停靠,當尺寸不足以被容納時會自動尋找最佳的位置進行浮動停靠的布局視圖。浮動布局的理念源於HTML/CSS中的浮動定位技術,因此浮動布局可以專門用來實現那些不規則布局或者圖文環繞的布局。根據浮動的方向不同,浮動布局可以分為左右浮動布局和上下浮動布局。
示例代碼:
-(void)loadView { [super loadView]; MyFloatLayout *S = [MyFloatLayout floatLayoutWithOrientation:MyLayoutViewOrientation_Vert]; S.wrapContentHeight = YES; S.padding = UIEdgeInsetsMake(10, 10, 10, 10); S.subviewMargin = 10; S.myWidth = 300; UIView *A = [UIView new]; A.mySize = CGSizeMake(80,70); [S addSubview:A]; UIView *B = [UIView new]; B.mySize = CGSizeMake(150,40); [S addSubview:B]; UIView *C = [UIView new]; C.mySize = CGSizeMake(70,40); [S addSubview:C]; UIView *D = [UIView new]; D.mySize = CGSizeMake(100,140); [S addSubview:D]; UIView *E = [UIView new]; E.mySize = CGSizeMake(150,40); E.reverseFloat = YES; [S addSubview:E]; UIView *F = [UIView new]; F.mySize = CGSizeMake(120,60); [S addSubview:F]; [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; A.backgroundColor = [UIColor greenColor]; B.backgroundColor = [UIColor blueColor]; C.backgroundColor = [UIColor orangeColor]; D.backgroundColor = [UIColor cyanColor]; E.backgroundColor = [UIColor blackColor]; F.backgroundColor = [UIColor whiteColor]; }路徑布局MyPathLayout
布局庫獨有
路徑布局是一種裡面的子視圖根據您提供的一條特定的曲線函數形成的路徑來進行布局的布局視圖。您需要提供一個實現曲線路徑的函數、一個特定的坐標體系、一種特定的子視圖在曲線上的距離設置這三個要素來實現界面布局。當曲線路徑形成後,子視圖將按相等的距離依次環繞著曲線進行布局。路徑布局主要應用於那些具有特定規律的不規則排列,而且效果很酷炫的的界面布局。
示例代碼:
-(void)loadView { [super loadView]; MyPathLayout *S = [MyPathLayout new]; S.mySize = CGSizeMake(320,320); S.coordinateSetting.isReverse = YES; S.coordinateSetting.origin = CGPointMake(0.5, 0.2); S.polarEquation = ^(CGFloat angle) { return 80 * (1 + cos(angle)); }; for (int i = 0; i < 4; i++) { UIView *A = [UIView new]; A.mySize = CGSizeMake(40,40); [S addSubview:A]; A.backgroundColor = [UIColor greenColor]; } [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; }Size Classes的支持
等價於iOS的Size Classes
MyLayout布局體系為了實現對不同屏幕尺寸的設備進行適配,提供了對Size Classes的支持。您可以將Size Classes和上述的6種布局搭配使用,以便實現各種設備界面的完美適配。系統提供2個UIView的擴展方法:
-(instancetype)fetchLayoutSizeClass:(MySizeClass)sizeClass; -(instancetype)fetchLayoutSizeClass:(MySizeClass)sizeClass copyFrom:(MySizeClass)srcSizeClass;
來實現對Size Classes的支持。比如下面的例子:
//默認所有設備的設置。 MyLinearLayout *rootLayout = [MyLinearLayout linearLayoutWithOrientation:MyLayoutViewOrientation_Vert]; rootLayout.padding = UIEdgeInsetsMake(10, 10, 10, 10); rootLayout.wrapContentHeight = NO; rootLayout.gravity = MyMarginGravity_Horz_Fill; //MySizeClass_wAny | MySizeClass_hCompact 表明的是iPhone設備的橫屏. MyLinearLayout *lsc = [rootLayout fetchLayoutSizeClass:MySizeClass_wAny | MySizeClass_hCompact copyFrom:MySizeClass_wAny | MySizeClass_hAny]; lsc.orientation = MyLayoutViewOrientation_Horz; lsc.wrapContentWidth = NO; lsc.gravity = MyMarginGravity_Vert_Fill;使用方法 直接拷貝 將github工程中的Lib文件夾下的所有文件復制到您的工程中。 將
#import "MyLayout.h"
頭文件放入到您的pch文件中,或者在需要使用界面布局的源代碼位置。
CocoaPods安裝
如果您還沒有安裝cocoapods則請先執行如下命令:
$ gem install cocoapods
為了用CocoaPods整合MyLayout到您的Xcode工程, 請建立如下的Podfile:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '7.0'
pod 'MyLayout', '~> 1.3.4'
然後運行如下命令:
$ pod install
演示效果圖
鏈接:
歡迎大家訪問我的github站點,並關注@歐陽大哥
Swift:TangramKit: https://github.com/youngsoft/TangramKit OC:MyLayout: https://github.com/youngsoft/MyLinearLayout通過本文的學習希望對您了解和學習ios開發的相關知識有一些好的幫助.感謝關注本站.我們將為您收集更多更好的ios開發教程.[db:作者簡介][db:原文翻譯及解析]
【iOS下的界面布局利器】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!