Вопрос: Передача данных между контроллерами просмотра


Я новичок в iOS и Objective-C и всей парадигме MVC, и я застрял в следующем:

У меня есть представление, которое действует как форма ввода данных, и я хочу дать пользователю возможность выбрать несколько продуктов. Продукты перечислены на другом UITableViewControllerи я включил множественные выборы.

Мой вопрос: как мне переносить данные из одного представления в другое? Я буду держать выбор на UITableViewв массиве, но как я могу передать это обратно в предыдущее представление формы ввода данных, чтобы его можно было сохранить вместе с другими данными в Core Data при отправке формы?

Я просмотрел и увидел, как некоторые люди объявляют массив в делегате приложения. Я читал кое-что о Синглтонах, но не понимаю, что это такое, и я кое-что прочитал о создании модели данных.

Каким будет правильный способ выполнения этого и как я буду заниматься этим?


1196


источник


Ответы:


Этот вопрос, кажется, очень популярен здесь, в stackoverflow, поэтому я решил попробовать и дать лучший ответ, чтобы помочь людям, начинающим в мире iOS, как я.

Надеюсь, этот ответ достаточно ясен, чтобы люди поняли и что я ничего не пропустил.

Передача данных вперед

Передача данных вперед в контроллер вида с другого контроллера. Вы должны использовать этот метод, если хотите передать объект / значение с одного контроллера вида на другой контроллер представлений, который вы можете нажать в стек навигации.

В этом примере мы будем иметь ViewControllerAа также ViewControllerB

Пропустить BOOLценность от ViewControllerAв ViewControllerBмы сделали бы следующее.

  1. в ViewControllerB.hсоздать свойство для BOOL

    @property (nonatomic, assign) BOOL isSomethingEnabled;
    
  2. в ViewControllerAвам нужно рассказать об этом ViewControllerBпоэтому используйте

    #import "ViewControllerB.h"
    

    Затем, где вы хотите загрузить представление, например. didSelectRowAtIndexили несколько IBActionвам нужно установить свойство в ViewControllerBпрежде чем вы нажмете его на навигационную стек.

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

    Это установит isSomethingEnabledв ViewControllerBв BOOLстоимость YES,

Передача данных вперед с помощью Segues

Если вы используете раскадровки, вы, скорее всего, используете segues и вам понадобится эта процедура для передачи данных вперед. Это похоже на приведенное выше, но вместо передачи данных перед тем, как вы нажимаете контроллер вида, вы используете метод, называемый

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

Итак, чтобы пройти BOOLиз ViewControllerAв ViewControllerBмы сделали бы следующее:

  1. в ViewControllerB.hсоздать свойство для BOOL

    @property (nonatomic, assign) BOOL isSomethingEnabled;
    
  2. в ViewControllerAвам нужно рассказать об этом ViewControllerBпоэтому используйте

    #import "ViewControllerB.h"
    
  3. Создайте сеанс из ViewControllerAв ViewControllerBна раскадровке и дать ему идентификатор, в этом примере мы назовем это "showDetailSegue"

  4. Затем нам нужно добавить метод к ViewControllerAкоторый вызывается, когда выполняется какой-либо segue, из-за этого нам нужно определить, какой вызов был вызван, а затем что-то сделать. В нашем примере мы проверим "showDetailSegue"и если это будет выполнено, мы пройдем наш BOOLзначение для ViewControllerB

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

    Если у вас есть свои взгляды, встроенные в контроллер навигации, вам нужно немного изменить метод выше на следующие

    -(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;
        }
    }
    

    Это установит isSomethingEnabledв ViewControllerBв BOOLстоимость YES,

Передача данных назад

Чтобы передать данные из ViewControllerBв ViewControllerAвам нужно использовать Протоколы и делегаты или Блоки , последний может использоваться как слабосвязанный механизм для обратных вызовов.

Для этого мы сделаем ViewControllerAделегат от ViewControllerB, Это позволяет ViewControllerBотправить сообщение обратно ViewControllerAпозволяя нам отправлять данные назад.

Для ViewControllerAбыть делегатом ViewControllerBон должен соответствовать ViewControllerBкоторый мы должны указать. Это говорит ViewControllerAкакие методы он должен реализовать.

  1. В ViewControllerB.h, ниже #import, но выше @interfaceвы указываете протокол.

    @class ViewControllerB;
    
    @protocol ViewControllerBDelegate <NSObject>
    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
    @end
    
  2. следующий еще в ViewControllerB.hвам необходимо настроить delegateсобственности и синтезировать в ViewControllerB.m

    @property (nonatomic, weak) id <ViewControllerBDelegate> delegate;
    
  3. В ViewControllerBмы вызываем сообщение на delegateкогда мы выходим на контроллер вида.

    NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
    [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
    
  4. Это для ViewControllerB, Сейчас в ViewControllerA.h, рассказать ViewControllerAимпортировать ViewControllerBи соответствовать его протоколу.

    #import "ViewControllerB.h"
    
    @interface ViewControllerA : UIViewController <ViewControllerBDelegate>
    
  5. В ViewControllerA.mвнедрить следующий метод из нашего протокола

    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
    {
        NSLog(@"This was returned from ViewControllerB %@",item);
    }
    
  6. Перед нажатием viewControllerBв стек навигации нам нужно сказать ViewControllerBчто ViewControllerAявляется его делегатом, иначе мы получим сообщение об ошибке.

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

Рекомендации


1547



стриж

Есть тонны и тонны объяснений здесь и вокруг StackOverflow, но если вы новичок, просто пытающийся получить что-то основное для работы, попробуйте посмотреть этот учебник YouTube (это помогло мне, наконец, понять, как это сделать).

Передача данных вперед в следующий контроллер просмотра

Ниже приведен пример, основанный на видео. Идея состоит в том, чтобы передать строку из текстового поля в First View Controller на метку в Second View Controller.

enter image description here

Создайте раскладку в построителе интерфейса. Чтобы сделать сегу, вы просто контроль нажмите на кнопку и перетащите ее на второй контроллер просмотра.

Контроллер первого взгляда

Код для первого контроллера просмотра

import UIKit

class FirstViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    // This function is called before the segue
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // get a reference to the second view controller
        let secondViewController = segue.destination as! SecondViewController

        // set a variable in the second view controller with the String to pass
        secondViewController.receivedString = textField.text!
    }

}

Второй контроллер просмотра

И код для второго контроллера просмотра

import UIKit

class SecondViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

    // This variable will hold the data being passed from the First View Controller
    var receivedString = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        // Used the text from the First View Controller to set the label
        label.text = receivedString
    }

}

Не забывайте

  • Подключите розетки для UITextFieldи UILabel,
  • Установите первый и второй контроллеры просмотра в соответствующие файлы Swift в IB.

Передача данных обратно в предыдущий контроллер просмотра

Чтобы передать данные с второго контроллера представления на первый контроллер представления, вы используете протокол и делегат , Это видео - очень четкая прогулка по этому процессу:

Ниже приведен пример, основанный на видео (с несколькими изменениями).

enter image description here

Создайте раскладку в построителе интерфейса. Опять же, чтобы сделать сегу, вы просто контроль перетащите кнопку на второй контроллер просмотра. Задайте идентификатор segue showSecondViewController, Кроме того, не забудьте подключить выходы и действия, используя имена в следующем коде.

Контроллер первого взгляда

Код для первого контроллера просмотра

import UIKit

class FirstViewController: UIViewController, DataEnteredDelegate {

    @IBOutlet weak var label: UILabel!

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showSecondViewController" {
            let secondViewController = segue.destination as! SecondViewController
            secondViewController.delegate = self
        }
    }

    func userDidEnterInformation(info: String) {
        label.text = info
    }
}

Обратите внимание на использование наших пользовательских DataEnteredDelegateпротокол.

Второй контроллер и протокол просмотра

Код для второго контроллера просмотра

import UIKit

// protocol used for sending data back
protocol DataEnteredDelegate: class {
    func userDidEnterInformation(info: String)
}

class SecondViewController: UIViewController {

    // making this a weak variable so that it won't create a strong reference cycle
    weak var delegate: DataEnteredDelegate? = nil

    @IBOutlet weak var textField: UITextField!

    @IBAction func sendTextBackButton(sender: AnyObject) {

        // call this method on whichever class implements our delegate protocol
        delegate?.userDidEnterInformation(info: textField.text!)

        // go back to the previous view controller
        _ = self.navigationController?.popViewController(animated: true)
    }
}

Обратите внимание, что protocolнаходится вне класса View Controller.

Вот и все. Запустив приложение, вы сможете отправлять данные с второго контроллера представления на первый.


127



M в MVC для «Модели», а в парадигме MVC роль классов моделей заключается в управлении данными программы. Модель противоположна представлению - представление знает, как отображать данные, но ничего не знает о том, что делать с данными, тогда как модель знает все о том, как работать с данными, но ничего о том, как ее отображать. Модели могут быть сложными, но их не обязательно - модель для вашего приложения может быть такой же простой, как массив строк или словарей.

Роль контроллера заключается в посредничестве между представлением и моделью. Поэтому им нужна ссылка на один или несколько объектов вида и один или несколько объектов модели. Предположим, что ваша модель представляет собой массив словарей, причем каждый словарь представляет одну строку в вашей таблице. Корневой вид для вашего приложения отображает эту таблицу, и он может отвечать за загрузку массива из файла. Когда пользователь решает добавить новую строку в таблицу, они нажимают какую-то кнопку, и ваш контроллер создает новый (изменяемый) словарь и добавляет его в массив. Чтобы заполнить строку, контроллер создает контроллер подробного представления и дает ему новый словарь. Контроллер подробного представления заполняет словарь и возвращает его. Словарь уже является частью модели, поэтому ничего другого не должно произойти.


117



Существуют различные способы, с помощью которых данные могут быть получены в другом классе в iOS. Например -

  1. Прямая инициализация после выделения другого класса.
  2. Делегирование - для передачи данных назад
  3. Уведомление - для передачи данных нескольким классам за один раз
  4. Сохранение в NSUserDefaults- для доступа к нему позже
  5. Одиночные классы
  6. Базы данных и другие механизмы хранения, такие как plist и т. Д.

Но для простого сценария передачи значения другому классу, распределение которого выполняется в текущем классе, наиболее распространенным и предпочтительным методом будет прямая настройка значений после выделения. Это делается следующим образом:-

Мы можем понять это, используя два контроллера - Контроллер1 и Контроллер2

Предположим, что в классе Controller1 вы хотите создать объект Controller2 и нажать его с переданным значением String. Это можно сделать следующим образом:

- (void)pushToController2 {

    Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
    [obj passValue:@"String"];
    [self pushViewController:obj animated:YES];
}

В реализации класса Controller2 будет существовать эта функция as-

@interface Controller2  : NSObject

@property (nonatomic , strong) NSString* stringPassed;

@end

@implementation Controller2

@synthesize stringPassed = _stringPassed;

- (void) passValue:(NSString *)value {

    _stringPassed = value; //or self.stringPassed = value
}

@end

Вы также можете напрямую установить свойства класса Controller2 так же, как это:

- (void)pushToController2 {

    Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
    [obj setStringPassed:@"String"];  
    [self pushViewController:obj animated:YES];
}

Чтобы передать несколько значений, вы можете использовать несколько параметров, например: -

Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
[obj passValue:@“String1” andValues:objArray withDate:date]; 

Или, если вам нужно передать более трех параметров, связанных с общей функцией, вы можете сохранить значения в классе Model и передать этот объект modelObject в следующий класс

ModelClass *modelObject = [[ModelClass alloc] init]; 
modelObject.property1 = _property1;
modelObject.property2 = _property2;
modelObject.property3 = _property3;

Controller2 *obj = [[Controller2 alloc] initWithNib:@"Controller2" bundle:nil];
[obj passmodel: modelObject];

Таким образом, коротко, если вы хотите -

1) set the private variables of the second class initialise the values by calling a custom function and passing the values.
2) setProperties do it by directlyInitialising it using the setter method.
3) pass more that 3-4 values related to each other in some manner , then create a model class and set values to its object and pass the object using any of the above process.

Надеюсь это поможет


85



After more research it seemed that Protocols and Delegates is the correct/Apple prefered way of doing this.

I ended up using this example

Sharing data between view controllers and other objects @ iPhone Dev SDK

Worked fine and allowed me to pass a string and an array forward and back between my views.

Thanks for all your help


74



I find simplest and most elegant version with passing blocks. Let's name view controller that waits for returned data as "A" and returning view controller as "B". In this example we want to get 2 values: first of Type1 and second of Type2.

Assuming we use Storyboard, first controller sets callback block, for example during segue preparation:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.destinationViewController isKindOfClass:[BViewController class]])
    {
        BViewController *viewController = segue.destinationViewController;

        viewController.callback = ^(Type1 *value1, Type2 *value2) {
            // optionally, close B
            //[self.navigationController popViewControllerAnimated:YES];

            // let's do some action after with returned values
            action1(value1);
            action2(value2);
        };

    }
}

and "B" view controller should declare callback property, BViewController.h:

// it is important to use "copy"
@property (copy) void(^callback)(Type1 *value1, Type2 *value2);

Than in implementation file BViewController.m after we have desired values to return our callback should be called:

if (self.callback)
    self.callback(value1, value2);

One thing to remember is that using block often needs to manage strong and __weak references like explained here


59



There is some good information in many of the answers given, but none address the question fully.

The question asks about passing information between view controllers. The specific example given asks about passing information between views, but given the self-stated newness to iOS, the original poster likely meant between viewControllers, not between views (without any involvement from the ViewControllers). It seems that all the answers focus on two view controllers, but what if the app evolves to need to involve more than two view controllers in the information exchange?

The original poster also asked about Singletons and the use of the AppDelegate. These questions need to be answered.

To help anyone else looking at this question, who wants a full answer, I'm going to attempt to provide it.

Application Scenarios

Rather than having a highly hypothetical, abstract discussion, it helps to have concrete applications in mind. To help define a two-view-controller situation and a more-than-two-view-controller situation, I am going to define two concrete application scenarios.

Scenario one: maximum two view controllers ever need to share information. See diagram one.

diagram of original problem

There are two view controllers in the application. There is a ViewControllerA (Data Entry Form), and View Controller B (Product List). The items selected in the product list must match the items displayed in the text box in the data entry form. In this scenario, ViewControllerA and ViewControllerB must communicate directly with each other and no other view controllers.

Scenario two: more than two view controllers need to share the same information. See diagram two.

home inventory application diagram

There are four view controllers in the application. It is a tab-based application for managing home inventory. Three view controllers present differently filtered views of the same data:

  • ViewControllerA - Luxury Items
  • ViewControllerB - Non-insured Items
  • ViewControllerC - Entire Home Inventory
  • ViewControllerD - Add New Item Form

Any time an individual item is created or edited, it must also synchronize with the other view controllers. For example, if we add a boat in ViewControllerD, but it is not yet insured, then the boat must appear when the user goes to ViewControllerA (Luxury Items), and also ViewControllerC (Entire Home Inventory), but not when the user goes to ViewControllerB (Non-insured Items). We need be concerned with not only adding new items, but also deleting items (which may be allowed from any of the four view controllers), or editing existing items (which may be allowed from the "Add New Item Form", repurposing the same for editing).

Since all the view controllers do need to share the same data, all four view controllers need to remain in synchronization, and therefore there needs to be some sort of communication to all other view controllers, whenever any single view controller changes the underlying data. It should be fairly obvious that we do not want each view controller communicating directly with each other view controller in this scenario. In case it is not obvious, consider if we had 20 different view controllers (rather than just 4). How difficult and error-prone would it be to notify each of the other 19 view controllers any time one view controller made a change?

The Solutions: Delegates and the Observer Pattern, and Singletons

In scenario one, we have several viable solutions, as other answers have given

  • segues
  • delegates
  • setting properties on view controllers directly
  • NSUserDefaults (actually a poor choice)

In scenario two, we have other viable solutions:

  • Observer Pattern
  • Singletons

A singleton is an instance of a class, that instance being the only instance in existence during its lifetime. A singleton gets its name from the fact that it is the single instance. Normally developers who use singletons have special class methods for accessing them.

+ (HouseholdInventoryManager*) sharedManager; {
    static dispatch_once_t onceQueue;
    static HouseholdInventoryManager* _sharedInstance;

    // dispatch_once is guaranteed to only be executed once in the
    // lifetime of the application
    dispatch_once(&onceQueue, ^{
        _sharedInstance = [[self alloc] init];
    });
    return _sharedInstance;
}

Now that we understand what a singleton is, let's discuss how a singleton fits into the observer pattern. The observer pattern is used for one object to respond to changes by another object. In the second scenario, we have four different view controllers, who all want to know about changes to the underlying data. The "underlying data" should belong to a single instance, a singleton. The "know about changes" is accomplished by observing changes made to the singleton.

The home inventory application would have a single instance of a class which is designed to manage a list of inventory items. The manager would manage a collection of household items. The following is a class definition for the data manager:

#import <Foundation/Foundation.h>

@class JGCHouseholdInventoryItem;

@interface HouseholdInventoryManager : NSObject
/*!
 The global singleton for accessing application data
 */
+ (HouseholdInventoryManager*) sharedManager;


- (NSArray *) entireHouseholdInventory;
- (NSArray *) luxuryItems;
- (NSArray *) nonInsuredItems;

- (void) addHouseholdItemToHomeInventory:(JGCHouseholdInventoryItem*)item;
- (void) editHouseholdItemInHomeInventory:(JGCHouseholdInventoryItem*)item;
- (void) deleteHoueholdItemFromHomeInventory:(JGCHouseholdInventoryItem*)item;
@end

When the collection of home inventory items changes, the view controllers need to be made aware of this change. The class definition above does not make it obvious how this will happen. We need to follow the observer pattern. The view controllers must formally observe the sharedManager. There are two ways to observe another object:

  • Key-Value-Observing (KVO)
  • NSNotificationCenter.

In scenario two, we do not have a single property of the HouseholdInventoryManager which could be observed using KVO. Because we do not have a single property which is easily observable, the observer pattern, in this case, must be implemented using NSNotificationCenter. Each of the four view controllers would subscribe to notifications, and the sharedManager would send notifications to the notification center when appropriate. The inventory manager does not need to know anything about the view controllers or instances of any other classes which may be interested in knowing when the collection of inventory items changes; the NSNotificationCenter takes care of these implementation details. The View Controllers simply subscribe to notifications, and the data manager simply posts notifications.

Many beginner programmers take advantage of the fact that there is always exactly one Application Delegate in the lifetime of the application, which is globally accessible. Beginning programmers use this fact to stuff objects and functionality into the appDelegate as a convenience for access from anywhere else in the application. Just because the AppDelegate is a singleton doesn't mean it should replace all other singletons. This is a poor practice as it places too much burden on one class, breaking good object-oriented practices. Each class should have a clear role that is easily explained, often just by the name of the class.

Any time your Application Delegate starts to get bloated, start to remove functionality into singletons. For example, the Core Data Stack should not be left in the AppDelegate, but should instead be put in its own class, a coreDataManager class.

References


46



There are multiple methods for sharing data.

  1. You can always share data using NSUserDefaults. Set the value you want to share with respect to a key of your choice and get the value from NSUserDefault associated to that key in the next view controller.

    [[NSUserDefaults standardUserDefaults] setValue:value forKey:key]
    [[NSUserDefaults standardUserDefaults] objectForKey:key]
    
  2. You can just create a property in viewcontrollerA. Create an object of viewcontrollerA in viewcontrollerB and assign the desired value to that property.

  3. You can also create custom delegates for this.


37



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 *destinationVC = (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.


37



The OP didn't mention view controllers but so many of the answers do, that I wanted to chime in with what some of the new features of the LLVM allow to make this easier when wanting to pass data from one view controller to another and then getting some results back.

Storyboard segues, ARC and LLVM blocks make this easier than ever for me. Some answers above mentioned storyboards and segues already but still relied on delegation. Defining delegates certainly works but some people may find it easier to pass pointers or code blocks.

With UINavigators and segues, there are easy ways of passing information to the subservient controller and getting the information back. ARC makes passing pointers to things derived from NSObjects simple so if you want the subservient controller to add/change/modify some data for you, pass it a pointer to a mutable instance. Blocks make passing actions easy so if you want the subservient controller to invoke an action on your higher level controller, pass it a block. You define the block to accept any number of arguments that makes sense to you. You can also design the API to use multiple blocks if that suits things better.

Here are two trivial examples of the segue glue. The first is straightforward showing one parameter passed for input, the second for output.

// Prepare the destination view controller by passing it the input we want it to work on
// and the results we will look at when the user has navigated back to this controller's view.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    [[segue destinationViewController]

     // This parameter gives the next controller the data it works on.
     segueHandoffWithInput:self.dataForNextController

     // This parameter allows the next controller to pass back results
     // by virtue of both controllers having a pointer to the same object.
     andResults:self.resultsFromNextController];
}

This second example shows passing a callback block for the second argument. I like using blocks because it keeps the relevant details close together in the source - the higher level source.

// Prepare the destination view controller by passing it the input we want it to work on
// and the callback when it has done its work.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    [[segue destinationViewController]

     // This parameter gives the next controller the data it works on.
     segueHandoffWithInput:self.dataForNextController

     // This parameter allows the next controller to pass back results.
     resultsBlock:^(id results) {
         // This callback could be as involved as you like.
         // It can use Grand Central Dispatch to have work done on another thread for example.
        [self setResultsFromNextController:results];
    }];
}

35



If you want to pass data from one controller to other try this code

FirstViewController.h

@property (nonatomic, retain) NSString *str;

SecondViewController.h

@property (nonatomic, retain) NSString *str1;

FirstViewController.m

- (void)viewDidLoad
   {
     // message for the second SecondViewController
     self.str = @"text message";

     [super viewDidLoad];
   }

-(IBAction)ButtonClicked
 {
   SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
   secondViewController.str1 = str;
  [self.navigationController pushViewController:secondViewController animated:YES];
 }

26