IOS開發(fā)之絕對布局和相對布局(屏幕適配)

網址:http://www.2cto.com/kf/201408/329492.html

? ?之前如果做過Web前端頁面的小伙伴們铆隘,看到絕對定位和相對定位并不陌生,并且使用起來也挺方便肮帐。在IOS的UI設計中也有絕對定位和相對定位咖驮,和我們的web前端的絕對定位和相對定位有所不同但又有相似之處。下面會結合兩個小demo來學習一下我們IOS開發(fā)中UI的絕對定位和相對定位训枢。在前面的博客中所用到的UI事例用的全是絕對定位,用我們Storyboard拖拽出來的控件全是絕對定位的忘巧,就是我們可以同改變組件的frame來改變組件的位置和大小恒界。而相對定位則不同,相對定位是參考組件周圍的元素來確定組件的大小或位置砚嘴,相對定位即約束和周圍組件的距離來布局的十酣,即layoutConstraint. 在布局中LayoutConstraint和Fram布局方式是不能并存的。

上面說了這么多了际长,可能說的不太明白耸采,還是那句話,怎么能少的了代碼和實例的支持呢工育,下面會通過屏幕適配的事例來用絕對布局和相對布局同時實現下面的描述效果虾宇。

我們要實現的效果:當上面的view的大小及位置改變時,為了不覆蓋掉下面的view,我們同時要改變下view的位置如绸。 或者說在我們4.0寸正常顯示的內容嘱朽,在3.5寸屏上也能正常顯示旭贬,即通常我們所說的屏幕的適配。為了便于觀察效果搪泳,我們可以用Slider控件來動態(tài)的改變上面view的大小稀轨,觀察下面view的位置變化,下面是我們要實現的效果圖:

1.用絕對布局來實現上述效果岸军,為了節(jié)省我們代碼編寫的時間奋刽,上面的控件是通過storyborad來實現的,然后在對應的ViewController里添加組件和控件回調的方法艰赞,主要是在slider滑動的時候來獲取slider的值杨名,然后動態(tài)的設置上面View的frame坐標(當然,如果讓view往四周擴展得計算一下新的fram的值猖毫,然后動態(tài)的修改)台谍,上面的view位置和大小改變了,那么下面的view不能被上面的覆蓋掉吁断,所以也得修改blackView的fram的值趁蕊。這種通過修改frame的值的方式來確定組件位置即為絕對布局

下面是由storyboard拖拽過來的屬性:

//把最上邊的view拖拽到我們的代碼中

@property (strong, nonatomic) IBOutlet UIView *myView;

//添加slider

@property (strong, nonatomic) IBOutlet UISlider *mySlider;

//添加下面黑色的view

@property (strong, nonatomic) IBOutlet UIView *blackView;

下面是當slider的值改變時要回調的方法:

//當slider的值改變的時候回調的方法

- (IBAction)sliderFunction:(id)sender

{

//獲取slider的當前值(在storyboard設置的范圍為0-120)

double value = self.mySlider.value;

//獲取myView的位置

CGRect frame = self.myView.frame;

//根據slider的值動態(tài)的設置myView的坐標和寬高,設置的時候view中心不變

frame.origin.x =? 120-value;

frame.origin.y = 66 * (1-value/120);

frame.size.height = 320-frame.origin.x*2;

frame.size.width = 320-frame.origin.x*2;

//更新myView的位置

self.myView.frame = frame;

//同時改變下面黑色view的坐標

CGRect bf = self.blackView.frame;

bf.origin.y = frame.size.height + frame.origin.y + 30;

self.blackView.frame = bf;

}

2.上面是我們的絕對布局的方式仔役,接下來要學習一下相對布局的方式掷伙。相對布局使用起來會比絕對布局要復雜一些,下面先做屏幕適配的例子又兵,圖一是在iPhone的4.0寸的效果圖任柜, 當我們不做任何處理的時候在3.5寸屏上是顯示不出來的如第二張圖:

(1)我們如何讓在3.5寸屏上也顯示正常呢,接下啦就是相對布局出出場的時候了沛厨,我們用相對布局的方式把最下面的view的位置改為相對于主視圖的底部和左邊的像素值固定宙地,同時設置slider的位置相對于下面的view的位置相對固定。也就是下面的veiw的位置改變逆皮,則上面的slider的位置也會改變宅粥,用storyboard修改如下:(第一張圖是修改最下面view的相對位置,第二張圖是設置我們slider為相對布局) 电谣,不需要在ViewController中添加任何動態(tài)嗎我們就可以實現屏幕的適配秽梅。

(2)那么我如何用相對布局實現上面那種view放大的效果呢,接下來我們需要新建一個工程剿牺,因為相對布局和絕對布局在同一個組件中無法并存企垦。在新建工程中用storyboard把我們用到的控件進行拖拽 繁调,界面和上面的是一樣的即硼。

(1)首先給我們最上面的View設置相對布局的屬性,如下面的圖一

(2)? 再給黑色的View設置相對布局的屬性遭赂,入下面的圖二所示:

(3) 設置上面兩個View相對中心對齊,選中上面的View,按著Ctrl往下面的View中拖拽臭增,在彈出的框中選中Center X入圖三

(4).給我們相應的組件在storyboard中添加上約束以后懂酱,怎樣來動態(tài)的改變最上面view的寬和高的約束范圍呢?(即改變水平約束和垂直約束的值)第一部就得把最上面的view的水平約束和垂直約束從我們的storyboard中把最上面View中我們要用的約束拖入到我們的Viewcontroller, 第一張圖是storyboard中約束所在的位置誊抛,第二張圖把約束添加到ViewController中列牺。

?? ? ?? ? ?? (5)至此我們用storyboard的工作已經做完,程序員是少不了敲代碼的拗窃,也只有正兒八經的敲代碼瞎领,程序員才會成長。所以嘍下面就是我們在ViewController中添加的代碼部分随夸。絕對布局直接改frame的坐標值就可以啦九默,那么在程序中我們如何去動態(tài)的改變我們約束的值呢?下面的代碼將會用到宾毒。 我們要做的事情就是在ViewController中通過改變slider的值來改變最上面View的水平約束和垂直約束驼修,水平約束和垂直約束的相關變量我們已經拖拽過來了,下面就需要在Slider回調的方法中來改變水平和垂直約束的值诈铛。先段代碼乙各,之后在說兩句。? ? ?? ? ?

//slider的值改變調用的方法

- (IBAction)sliderChange:(id)sender

{

//為了避免沖突移除myView的水平和垂直約束,注意是從主視圖上移除幢竹,因為約束是加載我們的主視圖上耳峦,即相對于我們的主視圖

[self.view removeConstraint:self.widthC];

[self.view removeConstraint:self.heightC];

//獲取slider的值

double sliderValue = self.mySlider.value;

//由slider的值重設我們的約束值,H代表水平約束, V代表垂直約束

NSString *widthValue = [NSString stringWithFormat:@"H:[_myView(%lf)]", sliderValue];

NSString *heightValue = [NSString stringWithFormat:@"V:[_myView(%lf)]", sliderValue];

//新建約束

NSArray *widthConstraint = [NSLayoutConstraint constraintsWithVisualFormat:widthValue options:0 metrics:nil views:NSDictionaryOfVariableBindings(_myView)];

//給水平約束重新賦值

self.widthC = widthConstraint[0];

//給垂直約束重新賦值

NSArray * heightConstraint = [NSLayoutConstraint constraintsWithVisualFormat:heightValue options:0 metrics:nil views:NSDictionaryOfVariableBindings(_myView)];

self.heightC = heightConstraint[0];

//往主視圖上添加新的約束

[self.view addConstraint:self.widthC];

[self.view addConstraint:self.heightC];

}

代碼說明:

? ? 1.一個組件中只能有一中約束焕毫,如在myView中我們已經有一個垂直約束蹲坷,我們如果再給他添加一個垂直約束的話,那么程序在運行時就會報錯邑飒,錯誤內容:“Unable to simultaneously satisfy constraints.……”循签;

? ? 2.所以在添加新的約束之前,我們得把之前加在我們組件中相應的約束給去掉幸乒;約束是加在我們對應組件的父視圖上懦底,移除也得從組件的父視圖上移除;

? ? 3.在設置約束的值的時候我們是以字符串的形式把參數傳遞給約束的罕扎,如:H:[_myView(200)] H代表水平約束,V代表垂直約束丐重。中括號里是我們要為那個組件添加約束以及約束的值是多少腔召;

? ? 4.給我們的約束更新我們新建的約束

? ? 5.在把更新的約束添加到我們的父視圖上,到此我們就可以實現上面我們上面用絕對布局實現的功能

補充說明:

? ? ?在絕對布局時我們還可以獲取屏幕的尺寸扮惦,通過屏幕的尺寸來計算我們組件所在的位置臀蛛,主要代碼如下:

//獲取屏幕大小

UIScreen *s = [UIScreen mainScreen];

//獲取屏幕邊界

CGRect bounds = s.bounds;

//獲取屏幕的高度

float height = bounds.size.height;

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子浊仆,更是在濱河造成了極大的恐慌客峭,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抡柿,死亡現場離奇詭異舔琅,居然都是意外死亡,警方通過查閱死者的電腦和手機洲劣,發(fā)現死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門备蚓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人囱稽,你說我怎么就攤上這事郊尝。” “怎么了战惊?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵流昏,是天一觀的道長。 經常有香客問我吞获,道長况凉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任衫哥,我火速辦了婚禮茎刚,結果婚禮上,老公的妹妹穿的比我還像新娘撤逢。我一直安慰自己膛锭,他們只是感情好,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布蚊荣。 她就那樣靜靜地躺著初狰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪互例。 梳的紋絲不亂的頭發(fā)上奢入,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音媳叨,去河邊找鬼腥光。 笑死,一個胖子當著我的面吹牛糊秆,可吹牛的內容都是我干的武福。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼痘番,長吁一口氣:“原來是場噩夢啊……” “哼捉片!你這毒婦竟也來了平痰?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤伍纫,失蹤者是張志新(化名)和其女友劉穎宗雇,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體莹规,經...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡赔蒲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了访惜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘹履。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖债热,靈堂內的尸體忽然破棺而出砾嫉,到底是詐尸還是另有隱情,我是刑警寧澤窒篱,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布焕刮,位于F島的核電站,受9級特大地震影響墙杯,放射性物質發(fā)生泄漏配并。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一高镐、第九天 我趴在偏房一處隱蔽的房頂上張望溉旋。 院中可真熱鬧,春花似錦嫉髓、人聲如沸观腊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梧油。三九已至,卻和暖如春州邢,著一層夾襖步出監(jiān)牢的瞬間儡陨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工量淌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留骗村,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓呀枢,卻偏偏與公主長得像叙身,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子硫狞,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內容