iOS开发之绝对布局和相对布局(屏幕适配)
? ? ? 在IOS的UI設(shè)計中也有絕對定位和相對定位,和我們的web前端的絕對定位和相對定位有所不同但又有相似之處。下面會結(jié)合兩個小demo來學(xué)習(xí)一下我們IOS開發(fā)中UI的絕對定位和相對定位。在前面的博客中所用到的UI事例用的全是絕對定位,用我們Storyboard拖拽出來的控件全是絕對定位的,就是我們可以同改變組件的frame來改變組件的位置和大小。而相對定位則不同,相對定位是參考組件周圍的元素來確定組件的大小或位置,相對定位即約束和周圍組件的距離來布局的,即layoutConstraint. 在布局中LayoutConstraint和Fram布局方式是不能并存的。
下面會通過屏幕適配的事例來用絕對布局和相對布局同時實現(xiàn)下面的描述效果。要實現(xiàn)的效果:當(dāng)上面的view的大小及位置改變時,為了不覆蓋掉下面的view,我們同時要改變下view的位置。 或者說在我們4.0寸正常顯示的內(nèi)容,在3.5寸屏上也能正常顯示,即通常我們所說的屏幕的適配。為了便于觀察效果,我們可以用Slider控件來動態(tài)的改變上面view果圖:
1.用絕對布局來實現(xiàn)上述效果,為了節(jié)省我們代碼編寫的時間,上面的控件是通過storyborad來實現(xiàn)的,然后在對應(yīng)的ViewController里添加組件和控件回調(diào)的方法,主要是在slider滑動的時候來獲取slider的值,然后動態(tài)的設(shè)置上面View的frame坐標(biāo)(當(dāng)然,如果讓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;
下面是當(dāng)slider的值改變時要回調(diào)的方法:
?
//當(dāng)slider的值改變的時候回調(diào)的方法
- (IBAction)sliderFunction:(id)sender
{
//獲取slider的當(dāng)前值(在storyboard設(shè)置的范圍為0-120)
double value = self.mySlider.value;
?
//獲取myView的位置
CGRect frame = self.myView.frame;
?
//根據(jù)slider的值動態(tài)的設(shè)置myView的坐標(biāo)和寬高,設(shè)置的時候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的坐標(biāo)
CGRect bf = self.blackView.frame;
bf.origin.y = frame.size.height + frame.origin.y + 30;
self.blackView.frame = bf;
?
}
?
2.上面是我們的絕對布局的方式,接下來要學(xué)習(xí)一下相對布局的方式。相對布局使用起來會比絕對布局要復(fù)雜一些,下面先做屏幕適配的例子,圖一是在iPhone的4.0寸的效果圖, 當(dāng)我們不做任何處理的時候在3.5寸屏上是顯示不出來的如第二張圖:
?
?
(1)如何讓在3.5寸屏上也顯示正常呢,接下啦就是相對布局出出場的時候了,我們用相對布局的方式把最下面的view的位置改為相對于主視圖的底部和左邊的像素值固定,同時設(shè)置slider的位置相對于下面的view的位置相對固定。也就是下面的veiw的位置改變,則上面的slider的位置也會改變,用storyboard修改如下:(第一張圖是修改最下面view的相對位置,第二張圖是設(shè)置我們slider為相對布局) ,不需要在ViewController中添加任何動態(tài)嗎我們就可以實現(xiàn)屏幕的適配。
(2)那么我如何用相對布局實現(xiàn)上面那種view放大的效果呢,接下來我們需要新建一個工程,因為相對布局和絕對布局在同一個組件中無法并存。在新建工程中用storyboard把我們用到的控件進行拖拽 ,界面和上面的是一樣的。
?
(1)首先給我們最上面的View設(shè)置相對布局的屬性,如下面的圖一
?
(2) 再給黑色的View設(shè)置相對布局的屬性,入下面的圖二所示:
?
(3) 設(shè)置上面兩個View相對中心對齊,選中上面的View,按著Ctrl往下面的View中拖拽,在彈出的框中選中Center X入圖三
(4).給我們相應(yīng)的組件在storyboard中添加上約束以后,怎樣來動態(tài)的改變最上面view的寬和高的約束范圍呢?(即改變水平約束和垂直約束的值)第一部就得把最上面的view的水平約束和垂直約束從我們的storyboard中把最上面View中我們要用的約束拖入到我們的Viewcontroller, 第一張圖是storyboard中約束所在的位置,第二張圖把約束添加到ViewController中。
(5)至此我們用storyboard的工作已經(jīng)做完,程序員是少不了敲代碼的,也只有正兒八經(jīng)的敲代碼,程序員才會成長。所以嘍下面就是我們在ViewController中添加的代碼部分。絕對布局直接改frame的坐標(biāo)值就可以啦,那么在程序中我們?nèi)绾稳討B(tài)的改變我們約束的值呢?下面的代碼將會用到。 我們要做的事情就是在ViewController中通過改變slider的值來改變最上面View的水平約束和垂直約束,水平約束和垂直約束的相關(guān)變量我們已經(jīng)拖拽過來了,下面就需要在Slider回調(diào)的方法中來改變水平和垂直約束的值。
//當(dāng)slider的值改變的時候回調(diào)的方法
- (IBAction)sliderFunction:(id)sender
{
//獲取slider的當(dāng)前值(在storyboard設(shè)置的范圍為0-120)
double value = self.mySlider.value;
?
//獲取myView的位置
CGRect frame = self.myView.frame;
?
//根據(jù)slider的值動態(tài)的設(shè)置myView的坐標(biāo)和寬高,設(shè)置的時候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的坐標(biāo)
CGRect bf = self.blackView.frame;
bf.origin.y = frame.size.height + frame.origin.y + 30;
self.blackView.frame = bf;
?
}
?
1.一個組件中只能有一中約束,如在myView中我們已經(jīng)有一個垂直約束,我們?nèi)绻俳o他添加一個垂直約束的話,那么程序在運行時就會報錯,錯誤內(nèi)容:“Unable to simultaneously satisfy constraints.……”; 代碼說明:
?
2.所以在添加新的約束之前,我們得把之前加在我們組件中相應(yīng)的約束給去掉;約束是加在我們對應(yīng)組件的父視圖上,移除也得從組件的父視圖上移除;
?
3.在設(shè)置約束的值的時候我們是以字符串的形式把參數(shù)傳遞給約束的,如:H:[_myView(200)] H代表水平約束,V代表垂直約束。中括號里是我們要為那個組件添加約束以及約束的值是多少;
?
4.給我們的約束更新我們新建的約束;
?
5.在把更新的約束添加到我們的父視圖上,到此我們就可以實現(xiàn)上面我們上面用絕對布局實現(xiàn)的功能
?
補充說明:
在絕對布局時我們還可以獲取屏幕的尺寸,通過屏幕的尺寸來計算我們組件所在的位置,主要代碼如下:
?
//獲取屏幕大小
UIScreen *s = [UIScreen mainScreen];
//獲取屏幕邊界
CGRect bounds = s.bounds;
//獲取屏幕的高度
float height = bounds.size.height;
?
轉(zhuǎn)載于:https://www.cnblogs.com/zhangz-1511/p/5042666.html
總結(jié)
以上是生活随笔為你收集整理的iOS开发之绝对布局和相对布局(屏幕适配)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小欢喜结局是啥
- 下一篇: iOS开发者帐号申请指南