Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have UITextField in secondViewController and a button in same view.
I want to get that UITextField text as a string to firstViewController.
Here my code.
SecondViewController.m
-(void)backToFirstView
{
NSString *str=disTxtFld.text;
FirstView *firstView=[[FirstView alloc]init];
firstView.discountStr=str;
[self.navigationController popViewControllerAnimated:YES];
}
FirstViewController.h
#property (nonatomic,strong) NSString *disStr;
FirstViewController.m
#synthesize disStr;
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"discount:%#",disStr);
}
When i`am trying to print that string in first view..it showing null value..
any suggestions...
The easiest way to do that is by using delegates. Please take a look here:
http://krodev.wordpress.com/2012/10/08/objective-c-delegates/
It's a step by step guide how to define and implement delegate.
Delegates are used to do just that what you are looking.
make a function in 1st-viewController
-(void)setStringFromSecondView:(NSStirng *)_value{
my_String=[NSString stringwithFormate:#"%#",_value];
}
and add this in header file
-(void)setStringFromSecondView:(NSStirng *)_value;
Now add a delegate variable in secondViewController
{
id delegateOfPrevious;
}
-(void)setDelegate:(id)_delegate{
delegateOfPrevious=_delegate
}
Now before Pushing Second View Controller in First viewController you have to set the delegate of FirstView Like this
secondViewController *secondView=[[secondViewController alloc] init....];
secondView.setDelegate=self;
...........
Now every Thing is set. you are one step away from success:
before popping the SecondViewController you can call this function in second view controller and it will set the value in first view controller.
[delegateOfPrevious setStringFromSecondView:textView.txt];
Do not forget to include firstViewController.h in SecondViewController.
I did this a day before for my own project and it is working fine.
Best way: Use an unwind segue in your storyboard to get back to the previous VC and pass the data along. For more info on this, watch the Storyboards WWDC session from 2012.
Other way: Use the delegate pattern. Create a protocol in your SecondViewController class called SecondViewControllerDelegate. Give it methods like "secondViewControllerDidFinish:" and "secondViewControllerDidCancel:". Have FirstViewController conform to that protocol and provide implementations for those methods. In those implementations, make sure the presented SecondViewController is dismissed. In the SecondViewController, create a delegate property of type id.
When FirstViewController presents SecondViewController, have it set itself as the SecondViewController's delegate. When SecondViewController completes whatever work that needs to be done, have them call the delegate methods and pass in the relevant data.
one best approach is declare your nsstring as global in app delegate.h synthesize it
fill it with data in second view controller then try to acess this nsstring in first view controller.
Related
I am transferring data from FirstView to SecondView after clicking on a button.
FirstView.h
#property (strong, nonatomic) NSString *stringOfFirstView;
FirstView.m
- (void)pushToSecond {
SecondView *controller = [[SecondView alloc] initWithNibName:#"SecondView" bundle:nil];
controller.stringOfSecondView = self.stringOfFirstView;
[self.navigationController pushViewController:controller animated:NO];
}
In SecondView, I have
SecondView.h
#property (strong, nonatomic) NSString *stringOfSecondView;
At SecondView,my goal is to go back to FirstView by clicking on back button and also want assign stringOfSecondView to stringOfFirstView as well
Question :
How can I assign stringOfSecondView to stringOfFirstView via clicking back button.
Just let you know, I am detecting an click event on back button in SecondView by doing
SecondView.m
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:YES];
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound)
NSLog(#"will show onto console");
}
But I am stuck how to do passing data back
Please advice if you have any clues about this issue.
I would use a delegate. So in your SecondView you need to create a protocol that sends data back to your FirstView. Your FirstView would become a delegate of the SecondView. There are tons of tutorials on how to make a delegate.
Basically you have 2 options:
In secondView: hold a reference to firstView
The more flexibile alternative: If you possibliy want to reuse the functionality, define a
protocol. Let firstView implement this protocol, and let firstView be the delegate for
secondView
In both cases, secondView will have an assign/weak-Property, where it stores a reference to firstView. And firstView will implement a Method, which receives a NSString and stores it in stringOfFirstView
It might help not to think of it as assigning via the click of the back button. Essentially, when you click the back button your FirstView will regain control. At the point where it is back in control, you can simply ask SecondView for the value of stringOfSecondView and store it wherever you like, such as in stringOfFirstView.
In order to ask the SecondView for this information, you may want to "remember" who the SecondView is by storing it's ID in an instance variable in FirstView. Also, remember to retain and release it properly if you are not doing automatic reference counting.
Just to complement ttran's answer, you can take a look here: http://mobiledevelopertips.com/objective-c/the-basics-of-protocols-and-delegates.html.
The basic idea is to create a Protocol (where you define methods that should be implemented (optionally or not) by the classes that adopt this Protocol. This means that your FirstViewController can adopt a Protocol, so your Second View Controller can know some methods that the First View Controller has.
So, the missing part is that the Second View Controller needs to have a reference to the First View Controller. You can do that via delegation (The delegate usually is a weak property).
Again, you can read more and understand this process by reading the basics of protocol and delegates.
Hello everyone — I am a beginner in iPhone programming and Core Data. I am currently trying to learn some of the theory behind Core Data, and have been using this tutorial to help me implement it in my app.
The tutorial teaches by making the main view a UITableViewController that lists the saved objects and another UITableViewController that saves objects (where you enter in the attributes).
The app that I am creating has 3 views. The main view is a plain UIViewController (it handles calculations), you are able to save your calculations by tapping a UIBarButtonItem that brings you to the second view where you enter in more specific attributes. Once you tap save, you are taken BACK to the main view, where you are able to tap a Show Saved button to access the UITableViewController containing saved objects.
I have included #imported the UITableViewController files into my main view's interface file, but when I run the program, I get an error on this line in my prepareForSegue method:
addShoeSizeTVC.managedObjectContext = self.managedObjectContext;
The error is "Property managedObjectContext not found on object of type 'SSFViewController*'" I understand the meaning of this error — I don't have any object called managedObjectContext in my SSFViewController class, but I figured that if I included my file that DOES contain managedObjectContext that it would still be recognized. I should add, that in the tutorial, the prepareForSegue method was contained in the list view for the segue to the add new object UITableViewController. I moved this method to my mainViewController.
I also get an error in my App Delegate in my ApplicationDidFinishLaunchingWithOptions method:
controller.managedObjectContext = self.managedObjectContext;
I understand that this stems from the same problem with the other error (it gives the same error message).
I do not understand how to pass data going from my viewA (mainView), to viewB (add object), back to viewA, then to viewC (view saved objects). I have heard about delegation and am using it in my prepareForSegue method in my SSFViewController main view:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"Add Object Segue"]) {
NSLog(#"Setting ObjectsTVC as a delegate of AddObjectTVC");
AddObjectTVC *addObjectTVC = segue.destinationViewController;
addObjectTVC.delegate = addObjectTVC.self;
addObjectTVC.managedObjectContext = addObjectTVC.self.managedObjectContext;
}
}
Also on the addObjectTVC.delegate = addObjectTVC.self; line I get a warning that says "Passing 'AddObjectTVC*' to parameter of incompatible type 'id'"
Do I have to set up an NSManagedContext or another delegation method in my main view? Or is it something that I must add to any of my Table views???
Thank you very much. I feel like this is a simple problem to solve, if provided with the right information. I am happy to post any other methods that I used if needed to solve the problem. I am a beginner, so it would be great if you could explain in a beginner-friendly way.
Thanks!
First of all, if you want data from ViewA to ViewB, insert a property in the ViewB and you can pass data from ViewA to this #property
Example
ViewB:
#property (nonatomic, strong) NSString *yourName;
(don't forget to call #synthesize yourName )
ViewA: (in prepareForSegue method)
"ViewB-Controller" *controller = segue.destinationViewController;
controller.yourName = self.name
--> name will be passed to ViewB
Second:
I prefer a delegate which send from ViewB to ViewA "Hey please save your data". It keeps your controller easy and smart, and you don't have to manage the save method from all view controllers. Delegate is an important chapter in iOS and it can be very frustrated for a beginner. (I was in the same situation 9 months before ;))
Search for a delegate example and try to understand how it works (learning by doing), if you have further question about delegate, I will friendly respond to your question.
It isn't the view controller that has the managedObjectContext property, but your UIManagedDocument.
The context is typically described as the 'scratch pad' in which your app will work with the data store.
I'm working on a pretty simple multiview app for the iOS and I've been following a great tutorial in an Apress book. I've basically got my rootViewController instantiated and displayed with the app delegate, and I've got a number of content viewControllers (6) which I'd like to swap in and out based on user input. However, in the book they perform their switches with a button on a toolbar placed in the rootView using Interface Builder. It fires a method in rootView that loads up the new content ViewController and displays it.
My problem is that I'd like to perform the content view switch (that lies in my rootViewController instance), but I'd like to trigger the switch action with a button that's in my content view (and is therefore unavailable as my File Owner is my contentViewController, whose reference is held inside my rootViewController).
Hopefully I've explained it well enough, please let me know if I should elaborate more. I appreciate any help!
You need to pass down a reference to your root view controller (RootViewController *rootViewController) when you create your content view either in a custom init method or by just assigning it after you created it: self.contentView.rootViewController = self;.
Now inside your content view you can then call the appropriate method in the root view controller to do the switch: [self.rootViewController switchView]. This call then can be triggered inside the method that is called when you press the button (IBAction method).
So this is what you need to do:
1) Create a property inside the your content view controller of type RootViewController
#class RootViewController;
#interface MyContentViewController : NSObject {
#private
RootViewController *rootViewController;
}
#property (retain) RootViewController *rootViewController;
and make sure it retains the reference.
2) Synthesis the property and add the callback to the root view controller that switches the view:
#implementation MyContentViewController
#synthesize rootViewController;
- (IBAction) switchView:(id) sender {
[rootViewController switchToNextView];
}
-(void) dealloc {
[rootViewController release];
[super dealloc];
}
Also release your retain reference at the end.
3) Assign the root view controller to the content view inside your RootViewController:
self.contentViewController = [[[MyContentViewController alloc]
initWithNibName:#"ContentView"
bundle:nil] autorelease];
self.contentViewController.rootViewController = self;
That should be all. I hope that helps you.
Well, you could simply create an IBAction in each of your child controllers that calls:
[self.parentViewController switchToDifferentController:(int) viewNumber]
and then implement the switchToDifferentController method in your root. Other than ignore the compiler warning that parentView might not implement that method, it might work.
However, that is a bit brittle, as you'd have to assume that it was the parent calling you and that nobody will forget to implement that method.
In general, you use the "delegate" concept for a child controller to ask its parent to do something. The general idea is that you declare a group of methods as a "protocol". Think of it as a contract between objects. One object can say "I promise to implement these methods," and another can then choose to send those messages to it. The contract allows the compiler/system to check for conformance. You'll see this in UITableView, where the OS provides a standard table, but it calls back to your code to provide the individual cells as needed.
To implement a protocol, you mustdo the following: (See code segments below
Declares a protocol for the conversation
Specify that the parent will follows that protocol
Create a delegate property in your child
When the parent is about to launch the child, it assigns itself as the delegate for that child.
When the child wants to switch, it calls the parent using that protocol
#protocol myVCDelegate
- (void)switchToDifferentController:(int) viewNumber ;
#end
#interface ParentViewController : UIViewController <VCDelegate>
#property(nonatomic, assign) id <VCDelegate> delegate
childController.delegate = self;
[self.delegate switchToDifferentController:kController5];
I hope that you will succeed in at least a little to clarify me how and what to do, I'm sure I'm wrong, so I really need an expert opinion.
I have two viewcontroller together with nibs what I want is to call function that is in first class from another ViewController, the problem is that another viewcontroller manages to call this function but the only thing I can see that is done is NSlog which outputs in the console (which I put in that position to know that the function is called)
example:
FirstViewController.m
-(void)drawingFunction:(NSString*)inputText{
NSLog("Feature was launched");
/* showing stuff in FirstView.xib */
}
SecondViewController.m
-(void)turnOnFunction:(id)sender{
FirstViewController *stuff= [[PrviViewController alloc] init];
[stuff drawingFunction:#"ShowAll"];
}
Basically when I call that function in the PrviViewController.m meaning without reference to the outside e.g.
[self drawingFunction:#"ShowAll"];
everything is well displayed, but when I try to call this function from SecondViewController.m all I see is just a "feature was launched" on the console
I really don't know what to do ...
if i get you right, the FirstViewController is on top of the view controller hierarchy (either within a navigation controller or presented modal)? So, if that is the case just creating an instance of SecondViewController and calling a function which should change the user interface on the view which corresponds to SecondViewController will do nothing at all.
You have to present the SecondViewController and its view with presentModalViewController:animated: for instance. After that the view of SecondViewController will be shown and you can do any changes on that view. Also calling the method drawingFunction: will act as you expect it.
Cheers,
Andreas
You're confusing instances with classes. You don't send messages (call functions) to classes, you send them to instances.
In this case, you have two entirely separate instances of FirstViewController. The first is created by loading the nib and the second is created in -[SecondController turnOnFunction:]. The drawingFunction: message is being sent to the second instance when you want it to be sent to the first.
You need to link the nib instance of FirstViewController to the SecondController instance. You can do that with an outlet in interface builder or you can assign it when you create the display the SecondController.
I have a simple UITableViewController in a UINavigationController that displays a list of strings from an array with the default Edit/Done button on the right-hand side of the navigation bar.
When pressing the Edit button, the UITableView animates correctly and shows the red minus icons to delete. Pressing the delete button removes the row from the table view and the array (implemented in the tableView:commitEditingStyle:forRowAtIndexPath: method of the UITableViewController).
I would now like to allow the user to add a row to the view (and add the string to the underlying array), but I'm not sure how to go about doing so. The commitEditingStyle method has else if (editingStyle == UITableViewCellEditingStyleInsert), but I don't know how I can get the user to input the string.
I've read the Table View Programming Guide (more specifically the example of adding a table-view row), but this seems to require a whole new UIViewController subclass just to get a string from the user.
Is there no easier way?
Creating another view controller is probably going to be the easiest way in the long run. You can present it modally by calling
SomeViewController* theViewController = [[SomeViewController alloc] init];
[self presentModalViewController: theViewController animated: YES];
[theViewController release];
When the theViewController is ready to go away it can call
[[self parentViewController] dismissModalViewControllerAnimated: YES];
OR
you can setup a protocol for your new view controller so it can notify your original view controller of completion and send a value back, if you wanted an NSString back you might use
#protocol MyViewControllerDelegate
- (void)myViewControllerDelegate: (MyViewController*)myViewController didFinishWithValue: (NSString*)theString;
#end
MyViewController would then have a delegate property
#interface MyViewController
{
id<MyViewControllerDelegate> delegate;
}
#property(nonatomic,assign) id<MyViewControllerDelegate> delegate;
#end
If you use the protocol method your original view controller will adopt that protocol and will dismiss the modal view itself when it receives this message.
I hope that helps out, it may seem a little complicated at first, but it makes gathering data very easy.
You could use a UIAlertView or similar class yourself. Just pop up the modal view to request the string, establish the right callbacks, then pop it in your dataSource.
You can also insert a cell with a UITextView and a "Tap to Edit" placeholder, then on the textView Callbacks, remove the textView and display the string. Further editing would need to drill down or do something else