iOS:視圖切換的第一種方式:模態窗口


一、UIModalController:模態窗口(一個控制器模態出另一個控制器的模態窗口)

  當我們在view controller A中模態顯示view controller B的時候,A就充當presenting view controller(彈出VC),而B就是presented view controller(被彈出VC)。官方文檔建議這兩者之間通過delegate實現交互,在被彈出的VC中定義delegate,然后在彈出VC中實現該代理,這樣就可以比較方便的實現兩者之間的交互。

 

模態風格:ModalTransitionStyle

 

    UIModalTransitionStyleCoverVertical = 0,   //垂直變化風格(默認)

 

    UIModalTransitionStyleFlipHorizontal,        //水平旋轉風格

 

    UIModalTransitionStyleCrossDissolve,       //閃換風格

 

    UIModalTransitionStylePartialCurl,            //上下翻書風格

 

 

1、以模態窗口的形式管理視圖,當前視圖關閉前其他視圖上的內容無法操作。

 

2、獲取不同的模態窗口(主要的屬性)

@property(nonatomic,readonly) UIViewController *presentedViewController ;//當前控制器模態出的窗口.

@property(nonatomic,readonly) UIViewController *presentingViewController;//模態出當前控制器的窗口

3、處理模態窗口(主要的方法)

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion);//顯示想要顯示的模態窗口

- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion);//關閉當前顯示的模態窗口

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id) //當前控制器模態另一個窗口並傳輸數據時調用的方法

4、用模態窗口的方式實現視圖的切換,即可以在stroybord中通過modal連接的方式將幾個UIController連接后去通過按鈕事件實現切換,也可以純代碼將storyboard中的幾個UIController連接后通過按鈕事件實現切換。

 

5、模態窗口一般采用設置代理或者通知的方式進行反向傳輸數據。

  設置代理協議或者創建通知中心都是由發送消息者完成的,由接受者設置代理或者注冊通知。

  通知方式:

a.有一個(單例)通知中心,負責管理iOS中的所有通知

b.需要獲取某種通知,必須注冊成為觀察者(訂閱)

c.不再需要取某種通知時,要取消注冊。

d.你可以向通知中心發送某種通知,通知中心會轉發給相應的觀察者(訂閱者)。

NSNotificationCenter *notification = [NSNotificationCenter defaultCenter] //創建通知中心單例對象 

- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject //通知中心收到接收者注冊的通知  

- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;//通知中心幫助發送者發送通知

- (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;//接收者接受完數據,通知中心幫助取消注冊

 6、presentedViewController 可以獲取到由當前控制器調用presentModalViewController展示的子視圖的控制器

     presentingViewController 則可以獲取到展示當前視圖的父級(上一級)視圖的控制器。

----------------------------------------------------------------------------------------------------------------------------------------------------------

  舉例:兩個視圖切換(FirstViewController、SecondViewController),模態窗口,並輸出數據

     類關聯:

   

 SecondViewController           FirstViewController

 

  當在storyboard中直接通過modal方式將控制器連接后,需要將storyboard中Segue的屬性identifier設置為modal,以便於當前控制器模態出另一個控制器的模態窗口和傳輸數據。

  第一步:拖出兩個視圖控制器到storyboard中,並已modal方式連接

  

 第二步:設置storyboard中的segue的屬性identifier標識符

 第三步:在FirstViewController控制器中模態出窗口並只進行正向傳輸數據 

 第四步:在SecondViewController中關閉被模態窗口,並接受數據 

 

  

  當storyboard中的控制器沒有通過modal方式直接連接時,可以通過代碼來連接,需要將storyboard中要被模態出窗口的控制器的identify的storyboardID設置一個標識。然后,首先創建要被模態顯示的控制器,即根據storyboard對象根據標識來加載要被模態窗口的控制器,最后進行模態窗口和傳輸數據。用這種方式傳輸數據時,如果是兩個以上的控制實現視圖切換,由於控制器耦合性太強,會出現錯錯誤,不建議使用。而是通過設置代理來實現數據的傳輸,即在被模態窗口的控制器中設置協議和代理,在模態窗口的控制器中實現代理的方法即可,大大降低了控制器中間的耦合性。

  《1》切換視圖,並不通過代理實現數據正向和反向傳輸

第一步:拖出兩個視圖控制器到storyboard中,未連接

 

第二步:將storyboard中要被模態出窗口的控制器SecondViewController的identify的storyboardID設置一個標識

第三步:在FirstViewController控制器中模態出窗口,並正向傳遞數據

 1 #import "ViewController.h"
 2 #import "SecondViewController.h"
 3 @interface ViewController ()
 4 @property (weak, nonatomic) IBOutlet UITextField *TextField;
 5 
 6 @end
 7 
 8 @implementation ViewController
 9 -(void)setTextWithBackInfo:(NSString *)info
10 {
11     self.TextField.text = info;
12 }
13 - (void)viewDidLoad {
14     [super viewDidLoad];
15 }
16 //純代碼創建模態顯示
17 - (IBAction)forwardClicked:(UIButton *)sender
18 {
19     //首先創建模態顯示的控制器
20     //從storyboard中加載控制器
21     UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
22     
23     //匹配storyboard的標識符
24     SecondViewController *secondVC = [storyboard instantiateViewControllerWithIdentifier:@"Second"];
25     
26     //正向傳數據
27     secondVC.info = self.TextField.text;
28     
29     //顯示模態窗口
30     [self presentViewController:secondVC animated:YES completion:nil];
31 }
32 
33 @end

第四步:在SecondViewController中關閉被模態出的窗口,並反向傳輸數據

    

        《2》切換視圖,通過代理實現數據正向和反向傳輸

  主要代碼如下:

  FirstViewController控制器中的代碼:

1 #import <UIKit/UIKit.h>
2 
3 @interface ViewController : UIViewController
4 
5 -(void)setTextWithBackInfo:(NSString *)info;
6 @end
 1 #import "ViewController.h"
 2 #import "SecondViewController.h"
 3 @interface ViewController ()<SecondViewControllerDelegate>
 4 @property (weak, nonatomic) IBOutlet UITextField *TextField;
 5 
 6 @end
 7 
 8 @implementation ViewController
 9 -(void)setTextWithBackInfo:(NSString *)info
10 {
11     self.TextField.text = info;
12 }
13 - (void)viewDidLoad {
14     [super viewDidLoad];
15 }
16 //純代碼創建模態顯示
17 - (IBAction)forwardClicked:(UIButton *)sender
18 {
19     //首先創建模態顯示的控制器
20     //從storyboard中加載控制器
21     UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
22     
23     //匹配storyboard的標識符
24     SecondViewController *secondVC = [storyboard instantiateViewControllerWithIdentifier:@"Second"];
25     
26     //正向傳數據
27     secondVC.info = self.TextField.text;
28     
29     //為了接受反向數據,將自己設置為模態窗口的代理,很好的降低了模態窗口的耦合性
30     secondVC.delegate = self;
31     
32     //顯示模態窗口
33     [self presentViewController:secondVC animated:YES completion:nil];
34 }
35 
36 #pragma mark -SecondViewController的代理方法
37 //通過代理接受模態窗口反向傳回的數據
38 -(void)SecondVC:(SecondViewController *)vc didFinishedWithInfo:(NSString *)info
39 {
40     self.TextField.text = info;
41 }
42 @end

    SecondViewController控制器中的代碼:

 1 #import <UIKit/UIKit.h>
 2 @protocol SecondViewControllerDelegate;
 3 @interface SecondViewController : UIViewController
 4 @property (weak, nonatomic) IBOutlet UILabel *label;
 5 @property (copy,nonatomic)NSString *info;
 6 //2.添加代理屬性
 7 @property (weak,nonatomic)id<SecondViewControllerDelegate> delegate;
 8 @end
 9 
10 
11 //1.定義協議
12 @protocol SecondViewControllerDelegate
13 
14 -(void)SecondVC:(SecondViewController*)vc didFinishedWithInfo:(NSString*)info;
15 
16 @end
 1 #import "SecondViewController.h"
 2 
 3 @interface SecondViewController ()
 4 @property (weak, nonatomic) IBOutlet UITextField *textField;
 5 @end
 6 
 7 @implementation SecondViewController
 8 - (IBAction)backButtonClicked:(UIButton *)sender
 9 {
10     //self.presentedViewController  當前控制器模態出的窗口
11     //self.presentingViewController 模態出當前控制器的窗口
12     
13     
14     //3.通過代理反向傳數據
15     [self.delegate SecondVC:self didFinishedWithInfo:self.textField.text];
16     
17     
18     //關閉模態窗口
19     [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
20     
21 }
22 
23 - (void)viewDidLoad {
24     [super viewDidLoad];
25     // Do any additional setup after loading the view.
26     
27     self.label.text = self.info;
28 }

 

    最后的演示結果為:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM