I am new to iOS. I am facing a problem passing the data between ViewControllers. I have three viewControllers (view_1 ,view_2 and view_3).
Here my setup:-
- Select view_1
- pushes view_2
- pushes view_3
I want to send the ViewController reference(id) of 'view_1' to 'view_3'. so i include include "view_3"
in 'view_1' and set the value into the variable of 'view_3'( using view_3 *v3=[[view_3 alloc] init ]; v3.reference=self;
). In the console it shows:
view controller :- ; <ViewController: 0x89e9540>
in the 'view_1' but in the 'view_3', in console it shows
view controller (null)
But when i used 'view_2' for passing this data its work. But how? I want to know this behaviour, And Is there any solution to creating this?
please help.
This Swift project on YouTube helped me to finally understand how to do this.
I set up a simple example along similar lines. Write some text in a text field, press the button, and it puts the text in a Label in the next View Controller.
Setup the storyboard
It's not very difficult. Create the storyboard layout in the Interface Builder. To make the segue you just control click on the button and drag over to the Second View Controller.
First View Controller
The code for the First View Controller is
Second View Controller
And the code for the Second View Controller is
Don't forget
UITextField
and theUILabel
.The process to pass the data on to a Third View Controller would be the same.
ya there is a solution but not the most proper way .
ViewController3.h
go to your ViewController3.m and above the the @interface add a variable like this
then some where inside the ViewController3.m
ViewController1 and import ViewController3 then do like this ..
in this case your function
getUser
will be called and you will getreceivingVariable= me
.Use Singleton pattern:
The Singleton pattern in software engineering is a design pattern that ensure a class has only one instance, and provide a global point of access to it.
As it has a unique instance, class variables and methods are shared in entire application/namespace.
Example:
And you can use it anywhere in your App like this:
Better and easy solution.
"Passing data to the destination Controller" when a segue is triggered will be achieved by overriding method
prepareForSegue:sender:
.Generally, you pass data and NOT the source view controller, to the destination view controller. "data" may be a certain aspect of your application "model". It's an object like "User", or perhaps an array containing "User", etc.
The destination view controller shall not have any knowledge of the source view controller. That means, the destination view controller does not need to import the header of the source view controller.
On the other hand, the source view controller may have knowledge of the concrete class of the destination view controller or a base class of the destination view controller, and thus will import the header of the destination view controller.
See: Configuring the Destination Controller When a Segue is Triggered
If you need some sort of "communication protocol" between the source and the destination, you might employ Delegation to communicate with other view controllers. This involves the definition of a @protocol (e.g. having a method
doneButton
) and a propertydelegate
which is defined in the destination view controller. The protocol should be defined in the header of the destination view controller, if it's specific to the destination view controller. Usually, you define tho protocol from the view point of the destination controller, and not from the requirements of the source controller.The source view controller then creates a delegate (unless, it itself is it already) and sets the
delegate
of of the destination view controller. The destination view controller will send the delegate methods to the delegate, and the delegate handles it.Now, passing "data" from a VC_A to VC_B should be straight forward. You should read a few examples which use
prepareForSegue:sender:
. For example, the destination view controller may have a propertydata
which represents the thing it should display. The source view controller must set this property inprepareForSegue:sender:
.Passing data from VC_A over VC_B to VC_C should be straight forward as well.
Note: Each view controller may tailor (separate, modify, prepare, slice, transform, etc.) its
data
to make it a suitabledata
for the next view controller.If VC_C needs data that is not available in its source view controller VC_B, then there are a couple of approaches to solve this. However, this is usually a sign of bad design.
You could have an application model, which is global. Suppose, your "application model" is an object of type
Document
. Suppose, at any time there is only one instance of that application model. Then, the model is a "Singleton", which could be accessed from anywhere in your app like so:However, the preferred way to get an instance of a model is in the first view controller which requires access to it, in this case: VC_A.
Then, VC_A passes a
Document
instance to the next view controller VC_B. And VC_B passes the document object to VC_C.You should read the official documentation "View Controller Programming Guide for iOS".
Example 1
Suppose, you have a list "Users". The list should be displayed in a table view controller, and there should also be a detail view, showing details of one User.
The table view controller will have a "data" property
users
:In UsersTableViewController.h:
(Strictly, this
user
property doesn't need to be public. For example, if the table view internally obtains the list of users itself, there is not need to access it from outside.The "users" array is the data of the table view which shall be displayed in rows. Each row shows a "summary" of a user.
More details of a user should be displayed in a detail view controller. The detail view controller's data is a single user of type
User
.When the user tabs a certain row in the table view, the detail view controller will be displayed. Before it will be displayed, the table view controller must configure the detail view controller: the table view controller assigns the detail view controller's "data property" the current selected user. Thus, the detail view controller should have a public property
user
:The table view controller configures the detail view controller in
prepareForSegue:sender:
:In UsersTableViewController.m
Example 2
The second example is more complex and uses "Delegation" as a means to establish a communication between controllers.
Caution:
Suppose we want to
from within the detail view.
These "data tasks" shall not be performed by the detail view controller itself, instead a delegate is responsible for these data tasks.
These data actions shall be handled by the delegate:
This protocol reflects the basic CRUD methods (Create, Read, Update, Delete).
Again, we don't want the Detail View Controller itself to perform these data methods, but instead this will be performed by an instance implementing the
UserDataSourceDelegateProtocol
. The detail view controller has a property of this delegate, and it sends these "data tasks" to the delegate.There may be several detail view controllers, all subclasses of abstract class
UserViewControllerBase
which handle the show, edit and create tasks. Deletion of a user can be performed in the table view and in the "Show User" view controller:ShowUserViewController
EditUserViewController
NewUserViewController
For example The
EditUserViewController
will sendviewController:dismissWithUpdatedUser:
when the user tabs the "back" button AND if the user has modified the user object. Now, the delegate may or may not allow to dismiss the detail view. It may disallow it when there are validation errors for example.The
UserDataSourceDelegateProtocol
protocol may be implemented in the root view controller, the table view controller for example. However, a separate class whose sole responsibility is to handle data tasks may be more appropriate. In the sample below, the table view controller will also be this data handler.The
UserDataSourceDelegateProtocol
may be defined in an extra header.In UsersTableViewController.m:
Here, the Table View Controller configures the Show User Detail View Controller:
The "Edit User" view controller is usually a destination view controller of the "Show User" view controller, which gets viewed when the user tabs the "Edit" button.
The "Show User" view controller will setup the delegate for the "Edit User" view controller gets the same delegate:
In ShowUserViewController.m
The data delegate may handle an updated user as follows:
In UsersTableViewController.m:
in Swift 4.0
Make sure
segue.destination
is the real different here.