亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

從零開始學ios開發(九):SwappingViews

2019-11-14 20:22:15
字體:
來源:轉載
供稿:網友

這篇的內容是切換Views,也是上一篇中提到的第三種當iphone發生旋轉后改變布局的方式,先回顧一下上一篇中提到的三種方式 1、使用Autosizing 2、寫code 3、重新弄個View,替換原先的View

切換View,顧名思義就是在兩個不同的View中間進行切換,那么我們至少需要有2個View,一個View展現當豎著(Portrait)拿iphone時的界面,另一個View展現當橫著(Landscape)拿iphone是的界面,當我們旋轉iphone時,就在這2個View之間進行切換,給用戶的感覺好像是用一個界面,其實我們是用2個View在進行替換。這樣做的好處是不必處理復雜的控件重新布局問題,但是壞處是因為是2個不同的View,我們必須用2套控件,然后當一個控件進行改變時,在另一個View中的“相同”控件也應進行改變(例如在一個View中被隱藏了,那在另一個View中也應該被隱藏,因為是同一個界面嘛,這點很重要。)

好,廢話少說,開始這篇的學習。

1)創建一個新的Single View項目,并命名為Swap

2)添加2個button 添加2個button,分別命名為Foo和Bar,長寬都為125,并像下圖一樣進行布局

3)添加另一個View(landscape view) 由于這個view是當前view(portrait view)的橫向版本,其界面上的控件類型、個數、功能應該和PRotrait view一樣,只是在布局上有些不同,因此最簡便的方法便是先復制一個portrait view,然后對界面上的控件位置大小從新布局。

選中BIDViewController.xib,在xib的editor dock中找到View 按住鍵盤上的option鍵,鼠標選中View并拖動鼠標,有一個綠色的加號出現,然后在View的同一層的下面放開鼠標,這樣一個View就復制好了。 (可能2個View重疊在一起,用鼠標移動上面的一個View,就會看到有2個View了)

在editor dock中選中新加的View,然后切換到Attributes inspector,找到Simulated Mertrics欄中的Orientation,將其屬性改成Landscape,這樣View就橫過來了

但是另一個button不見了,因為button位置的原因,另一個button沒有顯示在View中,我們現在editor dock中選中看不見的那個button 然后在Size inspector中將其起始點設成10,10 看不見的那個button出現了 重新對其布局

4)創建View的Outlet 因為我們要切換View,因此必須指定View的Outlet,這樣我們就可以在代碼中對View進行操作了,創建View的Outlet的方法和創建其他控件的Outlet的方法一樣,按下control鍵,鼠標選中View,拖動到BIDViewController.h中釋放,并命名即可。我們首先添加Portrait View的Outlet,命名為portrait 添加Landscape View的Outlet,命名為landscape

5)創建button的Outlet Collection 和以往的略微有些不同,由于我們有兩個View,但是這兩個View中的按鈕的作用是一樣的,所以我們在創建按鈕的Outlet時,可以使用Outlet集合,也就是Outlet Collection,Outlet Collection和Outlet的區別是,Outlet只能對應一個控件,Outlet Collection則可以對應多個控件,其實Outlet Collection就是一個Outlet的數組,里面可以存放任意多個Outlet,然后對其一一進行遍歷。有了Outlet Collection后,我們在寫Action的時候,只需要便利Outlet Collection,就可以其中包含的每個控件進行操作,會方便很多(否則你需要對每個控件聲明一個Outlet,然后一一操作,這個不僅增加代碼的復雜度,而且還很容易遺漏控件)。

添加Outlet Collection的方法和添加一般的Outlet方法一樣,選中Portrait View中的button Foo,按住control鍵,鼠標拖動到BIDViewController.h,釋放鼠標,在填出的框中改變類型Connection的類型,改成“Outlet Collection”,并命名為foos,單擊Connect完成添加。 添加完成后,切換到Landscape View,選中Foo按鈕,control + 鼠標拖動到已添加的Outlet Collection foos上,這樣Landscape View中Foo按鈕也加入到了foos集合中。

使用同樣的方法為兩個Bar按鈕添加Outlet Collection,并命名為bars。完成后的BIDViewController.h文件如下

復制代碼
#import <UIKit/UIKit.h>@interface BIDViewController : UIViewController@property (strong, nonatomic) IBOutlet UIView *portrait;@property (strong, nonatomic) IBOutlet UIView *landscape;@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *foos;@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *bars;@end
復制代碼

 

6)添加Action 為4個按鈕添加Action buttonTapped,只要添加一個Action,其他幾個按鈕連接到這個Action即可,完整的BIDViewController.h文件如下

復制代碼
@interface BIDViewController : UIViewController@property (strong, nonatomic) IBOutlet UIView *portrait;@property (strong, nonatomic) IBOutlet UIView *landscape;@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *foos;@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *bars;- (IBAction)buttonTaped:(id)sender;@end
復制代碼

7)實現View的切換 首先打開BIDViewController.m文件,然后添加一個宏定義在最上面(#import的下面)

#define degreesToRadians(x) (M_PI * (x) / 180.0)

這段宏的意思是將角度轉成弧度,在iphone旋轉時會用到,因為iphone的旋轉角度是根據弧度來計算的,并不是角度,因此我們需要進行一個簡單的轉換。M_PI是一個預定義的值,就是3.14159265358979323846264338327950288

重載willAnimateRotationToInterfaceOrientation方法,添加在最后一個@synthesize的后面,如下

復制代碼
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {        if(toInterfaceOrientation == UIInterfaceOrientationPortrait) {        self.view = self.portrait;        self.view.transform = CGAffineTransformIdentity;        self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(0));        self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);    }    else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {        self.view = self.landscape;        self.view.transform = CGAffineTransformIdentity;        self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90));        self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);    }    else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {        self.view = self.landscape;        self.view.transform = CGAffineTransformIdentity;        self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90));        self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);    }}
復制代碼

willAnimateRotationToInterfaceOrientation方法發生在旋轉開始之后但是還未真正旋轉之前,即旋轉這個命令已經發出了,但是還沒有開始旋轉這個動作。

上面的這段code,有幾個地方需要說明一下,我們拿一個if語句塊進行說明

self.view = self.landscape; 根據iphone的選擇方向,選擇顯示哪個View

self.view.transform = CGAffineTransformIdentity; 貌似是將view的旋轉狀態設置到默認狀態,即初始化一下,這個不太了解,網上查到的說法是:線性代數里面講的矩陣變換,這個是恒等變換???當 你改變一個view.transform屬性的時候需要先恢復默認狀態,然后再進行改變。

self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90)); view的旋轉弧度,將角度換算成弧度,然后進行旋轉。

self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0); CGRectMake在上一篇已經講解過,即設置起始點和大小,bounds屬性是第一次遇到,它和frame有些類似,但是不同的是,frame控件相對于父視圖的位置,而bounds則是控件自身的位置,即沒有相對于父視圖的概念,因為我們旋轉的都是view,因此其起始點自然都是(0.0 , 0.0)。

上面的這個旋轉方法可以當做模板來使用,每當遇到切換view的時候,就可以直接復制粘貼該方法。

(額外說明一個問題,仔細觀察上面的這個方法中CGRectMake中最后一個參數,最后一個參數是表面view的高度,但是是不是發現它少了20?原因是狀態欄,iphone頂部的狀態欄的高度是20,因此view的高度會減少20。)

8)實現buttonTappedAction 在BIDViewController.m中找到buttonTapped,添加代碼如下

復制代碼
- (IBAction)buttonTaped:(id)sender {    NSString *message = nil;        if([self.foos containsObject:sender])        message = @"Foo button pressed";    else        message = @"Bar button pressed";        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:message                                                    message:nil                                                   delegate:nil                                          cancelButtonTitle:@"ok"                                          otherButtonTitles:nil];    [alert show];}
復制代碼

這段代碼需要注意的就只有這一行

if([self.foos containsObject:sender])

foos是Outlet Collection對象,是一個NSArray,里面有一個containObject方法,查看是否存在某個對象,上面的if語句的意思就是判斷foos中是否包含觸發buttonTappedAction的對象,即判斷該Action是不是由2個Foo按鈕觸發的,如果不是,那么即使2個Bar按鈕觸發的。

9)編譯運行 點擊Foo,一個警告框彈出,告訴你Foo按鈕被點擊了

旋轉iphone,點擊Bar,同樣警告框填出,告訴你Bar按鈕被點擊了

Swap 1

10)更新buttonTapped 在開頭的時候,我們說過,因為是2個View進行切換,因此在一個View中發生的變化也要體現在另一個View中,我們在這里舉一個例子,當在一個View中點擊一個按鈕的時候,隱藏該按鈕,那么在另一個View中也要把對應的按鈕隱藏,將buttonTapped方法改成如下樣子

復制代碼
- (IBAction)buttonTaped:(id)sender {    /*    NSString *message = nil;        if([self.foos containsObject:sender])        message = @"Foo button pressed";    else        message = @"Bar button pressed";        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:message                                                    message:nil                                                   delegate:nil                                          cancelButtonTitle:@"ok"                                          otherButtonTitles:nil];    [alert show];    */        if([self.foos containsObject:sender]) {        for (UIButton *oneFoo in foos) {            oneFoo.hidden = YES;        }    }    else {        for (UIButton *oneBar in bars) {            oneBar.hidden = YES;        }    }        }
復制代碼

這里的for語句和C#中的foreach一樣,都是遍歷某個集合中的對象,首先判斷是那個按鈕觸發了buttonTapped,然后就將該按鈕所在的Outlet Collection中的所有對象隱藏,這樣當然也就隱藏了另一個View中的按鈕。

編譯運行,點擊bar按鈕,bar按鈕被隱藏 旋轉iphone,另一個View中的bar按鈕也被隱藏了

 

Swap All


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人欧美在线观看| 日韩免费精品视频| 欧美激情免费视频| 亚洲永久在线观看| 98视频在线噜噜噜国产| 伊人成人开心激情综合网| 亚洲精品福利在线| 日韩经典第一页| 日韩精品视频免费专区在线播放| 色老头一区二区三区在线观看| 亚洲欧美日韩精品久久奇米色影视| 欧美色视频日本高清在线观看| 中文字幕欧美亚洲| 亚洲成人精品视频| 日韩高清av在线| 国产网站欧美日韩免费精品在线观看| 精品国产一区二区三区在线观看| 亚洲午夜精品久久久久久性色| 精品久久香蕉国产线看观看gif| 91精品在线一区| www.日韩免费| zzijzzij亚洲日本成熟少妇| 久久成人在线视频| 久久影视免费观看| 欧美在线一区二区三区四| 国产噜噜噜噜久久久久久久久| 日韩av大片在线| 日韩精品免费在线| 亚洲午夜国产成人av电影男同| 亚洲国产欧美一区二区三区久久| 亚洲综合大片69999| 国产精品无码专区在线观看| 久久天天躁狠狠躁夜夜av| 永久免费毛片在线播放不卡| 亚洲在线免费视频| 欧美精品电影在线| 亚洲国产精品久久久| 热99精品只有里视频精品| 日本欧美在线视频| 91精品国产高清久久久久久91| 一区二区亚洲欧洲国产日韩| 欧美成人黑人xx视频免费观看| 亚洲精品免费一区二区三区| 欧美精品午夜视频| 成人在线免费观看视视频| 欧美激情欧美狂野欧美精品| 欧美中文字幕在线视频| 欧美性猛交xxxxx免费看| 国产精品精品视频| 中文字幕亚洲图片| 欧美寡妇偷汉性猛交| 国产亚洲精品91在线| 国内外成人免费激情在线视频网站| 性日韩欧美在线视频| 欧美激情喷水视频| 欧美特黄级在线| 日本久久91av| 成人午夜黄色影院| 欧美大成色www永久网站婷| 亚洲精美色品网站| 精品在线观看国产| 精品夜色国产国偷在线| 欧美另类极品videosbest最新版本| 日韩电影中文字幕av| 色www亚洲国产张柏芝| 亚洲日本aⅴ片在线观看香蕉| 亚洲一区二区三区在线视频| 亚洲欧美日韩图片| 热99久久精品| 精品丝袜一区二区三区| 中文字幕欧美亚洲| 亚洲精品一区久久久久久| 欧美裸体xxxxx| 久久九九热免费视频| 亚洲精品电影网在线观看| 日韩视频免费在线观看| 国产精品吴梦梦| 国产视频在线观看一区二区| 国内精品模特av私拍在线观看| 欧美日韩国产精品一区二区不卡中文| 国产中文字幕91| 国产精品午夜国产小视频| 福利精品视频在线| 国产精品女主播| 欧美性xxxxxx| 俺去亚洲欧洲欧美日韩| 精品在线小视频| 97精品视频在线| 96国产粉嫩美女| 国产精品久久一| 中文字幕综合在线| 91久久久久久| 日韩av最新在线| 中文字幕视频在线免费欧美日韩综合在线看| 亚洲男人天堂手机在线| 欧美xxxx做受欧美.88| 色777狠狠综合秋免鲁丝| 久久av在线播放| 国产精品丝袜久久久久久不卡| 国产日韩在线免费| 成人久久一区二区三区| 欧美精品在线观看91| 欧美色视频日本版| 亚洲一区精品电影| 国产情人节一区| 69av成年福利视频| 97超级碰碰碰久久久| 国产日韩欧美电影在线观看| 国产成人av网址| 日韩av电影免费观看高清| 96精品久久久久中文字幕| 清纯唯美亚洲综合| 亚洲视屏在线播放| 久久夜色精品亚洲噜噜国产mv| 久久亚洲精品中文字幕冲田杏梨| 久久99国产精品久久久久久久久| 视频直播国产精品| 日韩在线www| 亚洲欧美变态国产另类| 亚洲男人天堂2019| 九九视频直播综合网| 国产精品人人做人人爽| 久久99久久99精品中文字幕| 国产精品99蜜臀久久不卡二区| 国产精品久久久久久久久| 亚洲bt天天射| 亚洲欧洲免费视频| 国产精品偷伦免费视频观看的| 亚洲bt天天射| 亚洲精品综合精品自拍| 91亚洲一区精品| 中文欧美在线视频| 国语自产偷拍精品视频偷| 精品久久久久久国产| 欧美日韩国产中字| 91国产精品视频在线| 亚洲第一中文字幕| 欧美在线免费观看| 亚洲网址你懂得| 日韩欧美极品在线观看| 精品偷拍各种wc美女嘘嘘| 色爱精品视频一区| 91精品国产高清久久久久久| 国产福利视频一区二区| 黄色成人在线播放| 欧美在线视频一区二区| 精品国产31久久久久久| www国产精品com| 日韩av在线免费观看| 中文字幕日韩综合av| 亚洲欧美日韩国产中文专区| 亚洲男人天堂2023| 久久999免费视频| 日韩欧美视频一区二区三区| 欧美一区二区大胆人体摄影专业网站| 激情懂色av一区av二区av| 18性欧美xxxⅹ性满足| 伦伦影院午夜日韩欧美限制| 不卡av电影院| 国产91精品视频在线观看| 深夜福利日韩在线看| 热99在线视频| 国内精品久久久久久久久| 欧美www视频在线观看|