I have an app that has similar layout where a new ViewController will pop up when the button was clicked.
When the user clicks on one of the table cell, I would like to return this result to the main controller's function, please help.
There are different ways to do this.
- By using delegates.
- By implementing Notifications.
- Pass main view controller reference to the view controller and set some property or call method.
Now its up to you what way you will use. But according to my point of view implementing delegates will be the best way for this.
Following are some links from where you can understand how to pass data:
- http://www.raywenderlich.com/forums/viewtopic.php?f=10&t=3265
- http://www.tutorialspoint.com/ios/ios_delegates.htm
2nd link will take you to the delegates tutorial.
You might want to read about 'delegates'. Here is link to good SO discussion: What is a "delegate" in Objective C's iPhone development?
Related
I have been searching all over the web but I can't seem to find the answer to this.
Currently i am using presentViewController to start new ViewControllers, but on certain view controllers i do not dismiss it and call over it. I currently am not using any navigation controllers or anything like that.
I am just worried that if I call the same viewController again via presentViewController, that the same viewController would have 2 running instances.
Is it possible? Or does the iOS framework automatically reuse the idle viewController?
If so, how do i remove the idle view controllers?
Thank you! (I was holding back my question and tried to find it all over the web, so if you can point me in the right direction, it would be very helpful thanks!)
iOS will not reuse your view controller, you can easily check it yourself by printing your view controller in viewDidLoad, you will notice first that viewDidLoad is called every time, and next that all objects have different addresses.
Unless you create thousand of them, or the navigation of your app doesn’t let you come back to an “idle” view controller, I would not say this is an issue though.
I don’t see any clean way to remove a view controller from the memory without calling “dismiss”. You could try to:
- “refresh” your view with new data.
- use something like UIPageViewController if the workflow of your app allows this kind of behaviour.
- rework the navigation so you can dismiss the view before calling another one
Good luck
I am trying to make a tabbed application in Xcode that allows the user to take a photo and edit it on the FirstViewController class and when they are done display it on the SecondViewController.
When I started the project, Xcode automatically made the two viewControllers for me in the storyboard. What I need now is to find the instance of the second viewController that was generated so I can call a method and pass an argument (the UIImage) from the first view controller to the second like this.
FirstViewContoller.m
-(void) passImageToSecondVC (UIImage *) img
{
[<instanceOf_SecondViewController> receiveImg: img];
}
SecondViewContoller.m
-(void) receiveImage (UIImage *) img
{
//Code to display the image received
}
What Im asking is how can I find the name of the instance of the SecondViewController (shown by <> in the example code) generated by Xcode so I can call this method.
Although I'm very close to just doing this programmatically which I find much easier I wanna learn how to do this through the storyboard also I'm very open to hear other solutions to this problem. Thank you!
There's no way to do this through the storyboard. You don't access the view controller by its name. Each view controller has access to the tab bar controller through self.tabBarController. You can access individual controllers from the tab bar controller's viewControllers array. So, to get a reference to the controller in the second tab, you would use self.tabBarController.viewControllers[1].
Use delegates pattern.
Make one vc be a delegate of the other vc and communicate data between them. I think It's a common scenario.
https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html
i m new to ios app development.i m currently learning to work with navigation controller.Can anyone plz explain how to call -(UIInterfaceOrientation)navigationControllerPreferredInterfaceOrientationForPresentation: have implemented it in my code ,but it is not executing at all.
thankz in advance.
You don't call it, it's a delegate method that will be called by the navigation controller. You need to make whatever class you have the implementation of that method in, the delegate of the navigation controller.
The first method you mention is just a method which is called by the framework (if necessary) to get the "preferred Interface Orientation". For the system use this method you have to set more than one accepted interface orientation in your project setting and plist file.
The second method ´navigationController´ is inherited from ´UIViewController´ and gives a reference to the UINavigationController in which the UIViewController is embedded (means if there is no NavigationController it's nil). So it's a getter.
Now I think some more clarification in what you want to do with these methods would be useful, I mean you must have a reason why you ask, nobody just asks "why is there that method?"^^
I'm working on an iPhone app where I move through push through several view controllers. On the last on I [self.navigationController popToRootViewControllerAnimated:YES]
I want to ask is there a way to detect that I just came from ViewController7 when i return to the ViewController1?
The reason being i'd like the viewDidAppear to behave in a certain way if it is.
Otherwise is it possible to rerun the ViewDidLoad? (I'm presuming its not).
Thanks.
You could have your viewController1 conform to the UINavigationControllerDelegate protocol and become the UINavigationController's delegate. Then in navigationController:willShowViewController:animated: check if the controller to be shown is viewController1, check your UINavigationController's visibleViewController and set some variable in viewController1. Then in viewDidAppear you can animate appropriately.
I'd use the delegation design pattern to set a protocol method to send information back regarding what view controller you are in.
I'm currently refactoring my app to be sure the it's MVC compliant.
I would like to split the controller (MyController which extends UIController) and the view (HomeView which extends UIView) I set the view in myController using
self.view = [[HomeView alloc] init];
When I push an UIButton, a method is called in the view, and in this method I would like to call a method from the controller.
In my view
[zenModeBtn addTarget:self action:#selector(touchZenMode:) forControlEvents:UIControlEventTouchDown];
...
- (void) touchZenMode:(id) sender {
[myController playZenMode];
}
But having a reference to the controller in the view is really a bad practice isn't it ?
EDIT :
So in my UIViewController I've made this :
- (id) init {
HomeView* myHomeView = [[HomeView alloc] init];
[myHomeView.arcadeModeBtn addTarget:self action:#selector(touchArcadeMode) forControlEvents:UIControlEventTouchUpInside];
self.view = myHomeView;
return self;
}
is that correct ?
The view talking to your controller is no problem, as outlined by some answers here. E.g. a text field can notify its controller via the defined delegate methods.
However, your design is still seriously flawed. Your view has absolutely no business handling a button press itself. Your intuition that the view should not know about its controller is correct.
Your controller should know about the button and how to react to it being tapped. That's why a controller has button IBOutlets to tell the button to e.g. change its title or enabled state. And it has button handlers to react to UI events. It is the controller's job to handle this logic. It is the view's job to display the title, gray out or send a tap event back to the controller.
The only code you should put into a view is basically how to draw itself. Everything that cannot be handled by a controller.
The basic idea of the MVC pattern, as used in Cocoa Touch:
As described here: The Model-View-Controller Design Pattern
What you want to achieve, is a form of loose-, even blind maybe, coupling. By using protocols (for delegation mechanism), a View only knows that there is an object that adopts a specific protocol, it can 'talk' to.
Take the UITableView for instance. It does not need to know that there is a certain type of UIViewController that helps it gather data, but only that there is an object that adopts the UITableViewDatasourceDelegate and/or UITableViewDelegate; that object can be of any type.
In your edit, you use the target-action mechanism, which is another way of achieving loose-coupling. You set up the connection at runtime; your View does not know your Controller. Therefor: correct, apart from the comment #Mundi made about your init implementation being incomplete.
The view needs some way to communicate things back to the controller, ask it questions about what to do next, etc. So it's perfectly fine for the view to know something about the controller.
Some of the built-in views, like UITextField, define protocols they use to tell their delegate about what's going on, or ask it to do something. You typically implement the protocol in your controller. That way the view doesn't really know much about the controller, just enough to communicate. That makes your view more generic and reusable.
What you want to avoid is for your view to have direct links to your model. The role of the controller is to mediate between the view and the model. You should be able to completely change how the view is implemented without touching the model, and vice-versa.
You can put that method in a protocol in your view's interface:
#protocol MyViewDelegateProtocol <NSObject>
-(void)myMethod;
#end
you put a new property of NSObject type called delegate in your view.
you make your view controller comply to that protocol and when it inits the view assign the delegate property to self.
you implement myMethod in your view controller implementation.
and now you just call [delegate myMethod] from your view whenever you need it.