iOSノートの5種類のページ転送方式

22109 ワード

ページの値を伝える前に面白いジャンプを記録します:業務シーン:既存のページのジャンプ順序は:A-B-C-Dで、今C pushからDに着いた後に、Cpopを出して、ページの順序に達します:A-B-D.
C pushがDに着く前に、まずCの中でpopを1回でいいですよ.試してみてください.効果が得られるのは私の負けです.
ここには2つの案があります.1つ目は、Dのpopを書き換える方法で、彼のpopを特定のページ、つまりDに指定します.しかし、ここには問題があります.複数のページがDにpushできる場合、ここでpopを特定のページに指定すると問題が発生します.例えば、上はA-B-D、D popをBに指定します.もしページE-F-Dのジャンプがあれば、ここでD popは明らかにFに戻ります.指定したBではなく、Fに戻ります.popは分類して議論し、それぞれpopを指定ページに移すという人もいますが、この案は明らかに面倒で、興味があれば試してみてください.
2つ目は、ナビゲーションスタックを直接操作し、ジャンプが必要な位置で、まずCをナビゲーションスタックから削除し、それからDを入れて、私たちの問題を完璧に解決しました.
//C.m
D *result = [[D alloc] init];
NSMutableArray *vcs = self.navigationController.viewControllers.mutableCopy;
[vcs removeLastObject];
[vcs addObject:result];
[self.navigationController setViewControllers:vcs animated:YES];


本題に入ります:ページの価値伝達はとてもよく使う1つのもので、ここで比較的によく使う5種類を紹介します:属性の価値伝達、blockの価値伝達、代理の価値伝達、単例の価値伝達、通知の価値.(一)属性伝達実践案:第2のインタフェースのlableは第1のインタフェースtextFieldに入力されたテキスト実践手順を表示する:まずRootViewControllersとDetailViewControllersを確立する(detailページのlabelはrootページtextFieldに入力された内容を表示します)、DetailViewControlでtextStringプロパティを宣言し、送信された文字列を受信します.
//DetailViewControllerOne.h
#import 

@interface DetailViewControllerOne : UIViewController

@property (nonatomic , strong) NSString *textString;

@end

同時に、伝達された文字列を表示するためにLableを作成します.
//DetailViewControllerOne.m
#import "DetailViewControllerOne.h"

@interface DetailViewControllerOne ()

@end

@implementation DetailViewControllerOne

- (void)viewDidLoad {
    [super viewDidLoad];
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds)-40, 30)];
    label.backgroundColor = [UIColor orangeColor];
    label.font = [UIFont systemFontOfSize:20];
    label.numberOfLines = 0;
    label.text = self.textString;  //        
    [self.view addSubview:label];
    self.view.backgroundColor = [UIColor greenColor];
}


RootView ControlにDetailView Controlを導入し、文字列を入力するためにtextFieldプロパティを宣言します.
//RootViewControllers.m
#import "RootViewControllerOne.h"
#import "DetailViewControllerOne.h"

@interface RootViewControllerOne ()

@property(nonatomic , strong) UITextField *textField;

@end

@implementation RootViewControllerOne

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"    ";
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.textField];
    
    //         ,           ,          ,    
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    [self.view addGestureRecognizer:tap];
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(20, 200, CGRectGetWidth(self.view.bounds)-40, 40);
    [button setTitle:@"   " forState:UIControlStateNormal];
    button.titleLabel.font = [UIFont systemFontOfSize:20];
    button.backgroundColor = [UIColor greenColor];
    
    [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
}

-(UITextField *)textField {
    if (!_textField) {
        _textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds)-40, 40)];
        _textField.backgroundColor = [UIColor greenColor];
        _textField.placeholder = @"     ";
        
    }
    return _textField;
}

//         
- (void)handleTap:(id)sender {
    [_textField resignFirstResponder];
}

//    
-(void)clickAction:(id)sender {
    DetailViewControllerOne *dVC = [[DetailViewControllerOne alloc] init];
    dVC.textString = self.textField.text;  //  detail textString    textField     
    [self.navigationController pushViewController:dVC animated:NO];
}

まとめ:属性伝達の核心は、あるページで別のページの属性を使用することによって、この属性を利用して伝達する必要がある情報を保存し、別のページで前のページを使用して伝達できる情報を達成することです.
(二)Block値伝達の実践案:第2のページが第1のページに戻ると、第1のページのlableに第2のインタフェースtextFieldに入力されたテキスト実践手順が表示されます.まず、RootView Control lersとDetailView Control lersを確立します.(rootページのlabelはdetailページtextFieldに入力された内容を表示します)、RootViewControllersに表示用のLabelを新規作成します
//RootViewControllers.h
#import 

@interface RootViewControllerTwo : UIViewController

@property (nonatomic,retain) UILabel *label;

@end

DetailViewControllersで、値を伝えるためのBlock、Blockメソッド、コンテンツを入力するためのtextFieldを新規作成します.
//DetailViewControllers.h

#import 

typedef void (^ReturnTextBlock)(NSString *showText);//         

@interface DetailViewControllerTwo :UIViewController

@property (nonatomic,retain) UITextField *tf;

@property (nonatomic,copy) ReturnTextBlock returnTextBlock;//     Block  

- (void)returnText:(ReturnTextBlock)block;

@end

渡されたblockを自分の属性blockに割り当て、blockにデータを渡すタイミングを探します
//DetailViewControllers.m
#import "DetailViewControllerTwo.h"
#import "RootViewControllerTwo.h"

@implementation DetailViewControllerTwo

- (void)viewDidLoad {
    
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    //                  ,           UILabel 
    self.tf = [[UITextField alloc]initWithFrame:CGRectMake(20,100,CGRectGetWidth(self.view.bounds) - 40 , 40)];
    self.tf.tintColor = [UIColor orangeColor]; 
    self.tf.backgroundColor = [UIColor greenColor];
    self.tf.placeholder = @"     ";
    
    [self.view addSubview:self.tf];
    
    //      
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(20,300,CGRectGetWidth(self.view.bounds) - 40 , 40);
    button.backgroundColor = [UIColor redColor];
    [button setTitle:@"  " forState:UIControlStateNormal];
    [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:button];
}

/*           Block      ,     Block            
   returnTextBlock(.h      ) ,          */
-(void)returnText:(ReturnTextBlock)block{
    self.returnTextBlock = block;
}

//                 ,    :
-(void)viewWillDisappear:(BOOL)animated{
    if (self.returnTextBlock !=nil) {
        self.returnTextBlock(self.tf.text);
    }
}

//               ,         viewWillDisappear  
-(void)clickAction:(id)sender {
    [self.navigationController popViewControllerAnimated:NO];
}
@end


blockから渡されたデータを読み込みlabelに表示
//RootViewControllers.m
#import "RootViewControllerTwo.h"
#import "DetailViewControllerTwo.h"

@interface RootViewControllerTwo ()

@end

@implementation RootViewControllerTwo

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"Block  ";
    self.view.backgroundColor = [UIColor whiteColor];
    
    //      
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(20,300,CGRectGetWidth(self.view.bounds) - 40 , 40);
    button.backgroundColor = [UIColor blueColor];
    [button setTitle:@"   " forState:UIControlStateNormal];
    [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:button];
    
    //        
    self.label = [[UILabel alloc] initWithFrame:CGRectMake(20,100, CGRectGetWidth(self.view.bounds) - 40 , 40)];
    self.label.backgroundColor = [UIColor purpleColor];
    self.label.text = @"              ";//                   
    self.label.textColor = [UIColor whiteColor];
    [self.view addSubview:self.label];
}

-(void)clickAction:(id)sender{
    
    DetailViewControllerTwo * dVC =[[DetailViewControllerTwo alloc] init];//         ,          
    
    //                
    [dVC returnText:^(NSString *showText) {
        self.label.text = showText;
    }];
    
    [self.navigationController pushViewController:dVC animated:YES];
}

小結:実はblock伝値はやはり属性伝値に似ていますが、彼は値をコードブロックに保存し、関連付けて渡されたコードブロック(ページ1)と自分の属性コードブロック(ページ2)を通じて、コードブロック伝値(ページ2)を使って、ページ1に戻って、ページ1回コードブロックを調整して、コードブロックから渡された値を取得します.
(3)エージェント値伝達実践案:第1のインタフェースのlableは第2のインタフェースtextFieldに入力されたテキスト実践手順を表示する:まずRootViewControlとDetailViewControl(rootページのlabelはdetailページtextFieldに入力された内容を表示する)を確立し、まずエージェントとエージェントが実現する方法を宣言する
//DetailViewController.h
#import 

@class DetailViewControllerThree;
@protocol PassingValueDeletegate 

@optional
-(void)viewController:(DetailViewControllerThree *)viewController didPassingValueWithInfo:(id)info;

@end

@interface DetailViewControllerThree : UIViewController

@property(nonatomic, assign) id delegate;//      

@end

値を渡す必要があるタイミングで、渡す必要がある値をエージェントメソッドのパラメータに保存します.
//DetailViewController.m
#import "DetailViewControllerThree.h"

@interface DetailViewControllerThree ()
@property (nonatomic, strong) UITextField *textField;

@end

@implementation DetailViewControllerThree

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds)-40, 40);
    [button setTitle:@"  " forState:UIControlStateNormal];
    button.backgroundColor = [UIColor blueColor];
    [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:button];
    [self.view addSubview:self.textField];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    NSString *string;
    
    if ([_textField.text length] == 0) {
        string = @"         ";
    }else {
        string = _textField.text;
    }
    //      ,      
    //          ,                    
    if (self.delegate && [self.delegate respondsToSelector:@selector(viewController:didPassingValueWithInfo:)]) {
        [self.delegate viewController:self didPassingValueWithInfo:string];
    }
}

-(UITextField *)textField {
    if (!_textField) {
        _textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) - 40, 40)];
    }
    _textField.placeholder = @"     ";
    _textField.backgroundColor = [UIColor greenColor];

    return _textField;
}

-(void)clickAction:(id)sender {
    [self.navigationController popViewControllerAnimated:NO];
}

RootViewControllerがエージェントを実装し、そのエージェントを実装する方法を宣言します.このエージェントメソッドには、渡された値が含まれています.
//RootViewController.m
#import "RootViewControllerThree.h"
#import "DetailViewControllerThree.h"

@interface RootViewControllerThree () 

@property (nonatomic, strong) UILabel *showLabel;

@end

@implementation RootViewControllerThree
- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"    ";
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.showLabel];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds)-40, 40);
    [button setTitle:@"   " forState:UIControlStateNormal];
    button.titleLabel.font = [UIFont systemFontOfSize:20];
    button.backgroundColor = [UIColor greenColor];
    
    [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (UILabel *)showLabel {
    if (!_showLabel) {
        _showLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 200, CGRectGetWidth(self.view.bounds)-40, 40)];
    }
    _showLabel.text = @"             ";
    _showLabel.textColor = [UIColor whiteColor];
    _showLabel.backgroundColor = [UIColor purpleColor];
    return _showLabel;
}

-(void)clickAction:(id)sender {
    DetailViewControllerThree *dVC = [[DetailViewControllerThree alloc] init];

    dVC.delegate = self;
    
    [self.navigationController pushViewController:dVC animated:NO];
}

-(void)viewController:(DetailViewControllerThree *)viewController didPassingValueWithInfo:(id)info {
    _showLabel.text = info;  //          
}

小結:エージェントメソッドは比較的多く使われており、任意のインタフェース間で値を伝達するのに適しており、エージェントメソッドの実装を宣言するだけで、伝達された値を取得することができます.
(四)単例伝値実践案:第1のインタフェースのlableは第2のインタフェースtextFieldに入力されたテキストを表示し、同時に第2のインタフェースのlableは第1のインタフェースtextFieldに入力されたテキストを表示し、入力テキストは互いに実践ステップを伝達する:新しい単例
#import 

@interface AppStatus : NSObject {
    NSString *_contextStr;
}

@property(nonatomic,retain)NSString *contextStr;

+(AppStatus *)shareInstance;

@end

#import "AppStatus.h"

@implementation AppStatus
@synthesize contextStr = _contextStr;

static AppStatus *_instance = nil;

+(AppStatus *)shareInstance
{
    if (_instance == nil)
    {
        _instance = [[super alloc]init];
    }
    return _instance;
}

-(id)init
{
    if (self = [super init])
    {
        
    }
    return self;
}

@end
#import "RootViewControllerFour.h"
#import "AppStatus.h"
#import "DetailViewControllerFour.h"

@interface RootViewControllerFour ()

@property (nonatomic, strong) UILabel *label;
@property (nonatomic, strong) UITextField *textField;

@end

@implementation RootViewControllerFour

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    self.title = @"    ";
    
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btn.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds) -40, 40);
    [btn setTitle:@"Push" forState:UIControlStateNormal];
    btn.backgroundColor = [UIColor redColor];
    [btn addTarget:self action:@selector(pushAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
    [self.view addSubview:self.textField];
    self.label.frame = CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) -40, 40);
    
    self.label.backgroundColor = [UIColor greenColor];
    [self.view addSubview:self.label];
}

-(void)viewWillAppear:(BOOL)animated {
    if ([AppStatus shareInstance].contextStr.length !=0) {
        self.label.text = [AppStatus shareInstance].contextStr;
    } else {
        self.label.text = @"              ";
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(UITextField *)textField {
    if (!_textField) {
        _textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 200, CGRectGetWidth(self.view.bounds)-40, 40)];
    }
    _textField.placeholder = @"     ";
    _textField.backgroundColor = [UIColor purpleColor];
    _textField.textColor = [UIColor whiteColor];
    return _textField;
}

-(void)pushAction:(id)sender
{
//    _textField = (UITextField *)[self.view viewWithTag:1000];
    
    //                  (   )
    //  [[AppStatus shareInstance]setContextStr:tf.text];            
    [AppStatus shareInstance].contextStr = _textField.text;
    //  push      
    //pushViewController       +1,       
    DetailViewControllerFour *detailViewController = [[DetailViewControllerFour alloc]init];
    
    //  push      
    [self.navigationController pushViewController:detailViewController animated:YES];
    
}

#pragma mark - Getter & Setter
LabelGetter(label, NSTextAlignmentCenter, ColorFromRGB(0xffffff), [UIFont systemFontOfSize:15])
#import "DetailViewControllerFour.h"
#import "AppStatus.h"

@interface DetailViewControllerFour ()

@property (nonatomic, strong) UILabel *label;
@property (nonatomic, strong) UITextField *textField;

@end

@implementation DetailViewControllerFour

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    
    self.label.frame = CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) -40, 40);
    self.label.backgroundColor = [UIColor greenColor];
    [self.view addSubview:self.label];
    
    self.textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 200, CGRectGetWidth(self.view.bounds) -40, 40)];
    self.textField.placeholder = @"     ";
    self.textField.backgroundColor = [UIColor purpleColor];
    self.textField.textColor = [UIColor whiteColor];
    [self.view addSubview:self.textField];
    
    UIButton *button =[UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds) -40, 40);
    button.backgroundColor = [UIColor redColor];
    [button setTitle:@"  " forState:UIControlStateNormal];
    [button addTarget:self action:@selector(doneAction:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:button];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)viewWillAppear:(BOOL)animated {
    if ([AppStatus shareInstance].contextStr.length !=0) {
        self.label.text = [AppStatus shareInstance].contextStr;
    } else {
        self.label.text = @"              ";
    }
}

//pop      
-(void)doneAction:(id)sender {
    //    
    [AppStatus shareInstance].contextStr = _textField.text;
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark - Getter & Setter
LabelGetter(label, NSTextAlignmentCenter, ColorFromRGB(0xffffff), [UIFont systemFontOfSize:15])

(五)通知伝値実践案:第1のインタフェースのlableは第2のインタフェースtextFieldに入力されたテキスト実践手順を表示する:まずRootViewControllersとDetailViewControllersを確立する(rootページのlabelはdetailページtextFieldが入力した内容を表示します)まず、RootView Controlに通知傍受を登録し、ページが消えたときにその通知を削除します(登録と削除に対応します)
#import "RootViewControllerFive.h"
#import "DetailViewControllerFive.h"

#define xbyNotification @"labelChange"

@interface RootViewControllerFive ()

@property (nonatomic, strong) UILabel *label;

@end

@implementation RootViewControllerFive

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor greenColor];
    self.title = @"    ";
    
    [self.view addSubview:self.label];
    
    UIButton *button  = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds)-40, 40);
    [button setTitle:@"  " forState:UIControlStateNormal];
    [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];
    button.backgroundColor = [UIColor blueColor];
    [self.view addSubview:button];
}

-(void)viewWillAppear:(BOOL)animated {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(labelTextChange:) name:xbyNotification object:nil];
}

//             ,  GG ,       
//-(void)viewWillDisappear:(BOOL)animated {
//    [super viewDidDisappear:animated];
//    [[NSNotificationCenter defaultCenter] removeObserver:self];
//}
//      
-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

-(UILabel *)label {
    if (!_label) {
        _label = [[UILabel alloc ] initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds)-40, 40)];
        _label.textAlignment = NSTextAlignmentCenter;
        _label.backgroundColor = [UIColor purpleColor];
        _label.text = @"        ";
        _label.textColor = [UIColor whiteColor];
    }
    
    return _label;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)clickAction:(id)sender {
    [self.navigationController pushViewController:[DetailViewControllerFive new] animated:NO];
}

-(void)labelTextChange:(NSNotification *)sender {
    NSDictionary *dic = sender.userInfo;
    self.label.text = dic[@"info"];
//    NSLog(@"    ");
}

ボタンクリック時に通知を送信
#import "DetailViewControllerFive.h"

#define xbyNotification @"labelChange"

@interface DetailViewControllerFive ()

@property (nonatomic, strong) UITextField *textField;

@end

@implementation DetailViewControllerFive

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self.view addSubview:self.textField];
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(20, 300, CGRectGetWidth(self.view.bounds)-40, 40);
    [button setTitle:@"    " forState:UIControlStateNormal];
    button.backgroundColor = [UIColor redColor];
    [button addTarget:self action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:button];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(UITextField *)textField {
    
    if (!_textField) {
        _textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) - 40, 40)];
    }
    _textField.placeholder = @"     ";
    _textField.backgroundColor = [UIColor greenColor];
    
    return _textField;
}

-(void)clickAction:(id)sender {
    [[NSNotificationCenter defaultCenter] postNotificationName:xbyNotification object:self userInfo:@{@"info":_textField.text}];
    [self.navigationController popViewControllerAnimated:NO];
}

概要:登録通知と削除通知は、通知が送信されたメッセージを受信するには、通知名が同じである必要があります.
Demoダウンロード