Passing Data between View Controllers

链接:http://stackoverflow.com/questions/5210535/passing-data-between-view-controllers

1、

This question seems to be very popular here on stackoverflow so I thought I would try and give a better answer to help out people starting in the world of iOS like me.

I hope this answer is clear enough for people to understand and that I have not missed anything.

Passing Data Forward

Passing data forward to a view controller from another view controller. You would use this method if you wanted to pass an object/value from one view controller to another view controller that you may be pushing on to a navigation stack.

For this example we will have ViewControllerA and ViewControllerB

To pass a BOOL value from ViewControllerA to ViewControllerB we would do the following.

  1. in ViewControllerB.h create a property for the BOOL

    @property(nonatomic) BOOL *isSomethingEnabled;
  2. in ViewControllerA you need to tell it about ViewControllerB so use an

    #import "ViewControllerB.h"

    Then where you want to load the view eg. didSelectRowAtIndex or some IBAction you need to set the property in ViewControllerB before you push it onto nav stack.

    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
    viewControllerB.isSomethingEnabled = YES;
    [self pushViewController:viewControllerB animated:YES];

    This will set isSomethingEnabled in ViewControllerB to BOOL value YES.

Passing Data Forward using Segues

If you are using Storyboards you are most likely using segues and will need this procedure to pass data forward. This is similar to the above but instead of passing the data before you push the view controller, you use a method called

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

So to pass a BOOL from ViewControllerA to ViewControllerB we would do the following:

  1. in ViewControllerB.h create a property for the BOOL

    @property(nonatomic) BOOL *isSomethingEnabled;
  2. in ViewControllerA you need to tell it about ViewControllerB so use an

    #import "ViewControllerB.h"
  3. Create a the segue from ViewControllerA to ViewControllerB on the storyboard and give it an identifier, in this example we'll call it "showDetailSegue"

  4. Next we need to add the method to ViewControllerA that is called when any segue is performed, because of this we need to detect which segue was called and then do something. In our example we will check for "showDetailSegue" and if thats performed we will pass our BOOL value to ViewControllerB

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        if([segue.identifier isEqualToString:@"showDetailSegue"]){
            ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;
            controller.isSomethingEnabled = YES;
        }
    }

    If you have your views embedded in a navigation controller you need to change the method above slightly to the following

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        if([segue.identifier isEqualToString:@"showDetailSegue"]){
            UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
            ViewControllerB *controller = (ViewControllerB *)navController.topViewController;
            controller.isSomethingEnabled = YES;
        }
    }

    This will set isSomethingEnabled in ViewControllerB to BOOL value YES.

Passing Data Back

To pass data back from ViewControllerB to ViewControllerA you need to use Protocols and Delegates or Blocks, the latter can be used as a loosely coupled mechanism for callbacks.

To do this we will make ViewControllerA a delegate of ViewControllerB. This allows ViewControllerB to send a message back to ViewControllerA enabling us to send data back.

For ViewControllerA to be delegate of ViewControllerB it must conform to ViewControllerB's protocol which we have to specify. This tells ViewControllerA which methods it must implement.

  1. In ViewControllerB.h, below the #import, but above @interface you specify the protocol.

    @class ViewControllerB;
    
    @protocol ViewControllerBDelegate <NSObject>
    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
    @end
  2. next still in the ViewControllerB.h you need to setup a delegate property and synthesize in ViewControllerB.m

    @property (nonatomic, weak) id <ViewControllerBDelegate> delegate;
  3. In ViewControllerB we call a message on the delegate when we pop the view controller.

    NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
    [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
  4. That's it for ViewControllerB. Now in ViewControllerA.h, tell ViewControllerA to import ViewControllerB and conform to its protocol.

    #import "ViewControllerB.h"
    
    @interface ViewControllerA : UIViewController <ViewControllerBDelegate>
  5. In ViewControllerA.m implement the following method from our protocol

    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
    {
        NSLog(@"This was returned from ViewControllerB %@",item);
    }
  6. The last thing we need to do is tell ViewControllerB that ViewControllerA is its delegate before we push ViewControllerB on to nav stack.

    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
    viewControllerB.delegate = self
    [[self navigationController] pushViewController:viewControllerB animated:YES];

References

2、

Passing data back from ViewController 2(destination) to viewController 1(Source) is the more interesting thing. Assuming you use storyBoard those are all the ways i found out:

  • Delegate
  • Notification
  • User defaults
  • Singleton

Those were discussed here already.

I found there are more ways:

-Using Block callbacks:

use it in the prepareForSegue method in the VC1

NextViewController* destination = (NextViewController*) segue.destinationViewController;
    [destinationVC setDidFinishUsingBlockCallback:^(NextViewController *destinationVC)
    {
         self.blockLabel.text = destination.blockTextField.text;
    }];

-Using storyboards Unwind (Exit)

Implement a method with a UIStoryboardSegue argument in VC 1, like this one:

-(IBAction)UnWindDone:(UIStoryboardSegue *)segue { }

In the storyBoard hook the "return" button to the green Exit button(Unwind) of the vc. Now you have a segue that "goes back" so u can use the destinationViewController property in the prepareForSegue of VC2 and change any property of VC1 before it goes back.

  • Another option of using storyboards Undwind (Exit) - you can use the method you wrote in VC1

    -(IBAction)UnWindDone:(UIStoryboardSegue *)segue {
        NextViewController *nextViewController = segue.sourceViewController;
        self.unwindLabel.text = nextViewController.unwindPropertyPass;
    } 

    And in the prepareForSegue of VC1 you can change any property you want to share.

In both unwind options you can set the tag property of the button and check it in the prepareForSegue.

Hope i added something to the discussion.

:) Cheers.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Pointers and integers are both data types in programming, but they serve different purposes and have different characteristics. An integer is a data type that represents a whole number, either positive, negative, or zero. It is typically used for counting, indexing, and arithmetic operations. A pointer, on the other hand, is a variable that stores the memory address of another variable. It is used to reference and manipulate data stored in memory. Pointers are commonly used in dynamic memory allocation, passing data between functions, and working with complex data structures. Here are some key differences between pointers and integers: 1. Size: Integers typically require a fixed number of bytes to store, depending on the data type (e.g., an int may require 4 bytes). Pointers, on the other hand, generally require more bytes to store (e.g., 8 bytes on a 64-bit system) because they store a memory address. 2. Type safety: Integers are type-safe, meaning they can only store values that are within their defined range and data type. Pointers, however, are not type-safe and can be used to reference any data type, regardless of its size or structure. 3. Null value: Integers can be set to zero to represent a null value, but this is not always reliable because zero may be a valid value for the data type. Pointers, on the other hand, can be set to a null value (represented by the constant NULL or 0) to indicate that they are not currently pointing to any valid memory address. 4. Memory management: Integers do not require any special memory management because they are stored on the stack or in registers. Pointers, however, require more careful memory management because they store memory addresses that must be allocated and deallocated dynamically. In summary, integers and pointers are both important data types in programming, but they serve different purposes and have different characteristics. Integers are used for counting and arithmetic operations, while pointers are used to reference and manipulate data stored in memory.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值