Detect When Return to a View - iphone

HI
How can I detect when I return to a view? I have an iPad app in development and I want to do something upon returning to a certain view. How can I do this?
Thanks.

Override the -viewWillAppear: or -viewDidAppear: method in the UIViewController subclass that manages the view. For example:
#implementation MyController
- (void)viewDidAppear:(BOOL)animated
{
// Do whatever you like here, for example...
[self setSomeBOOL:YES];
// Call super (per Apple's documentation).
[super viewDidAppear:animated];
}
#end

If you're using UITabBarController you can take a look at UITabBarControllerDelegate protocol:
– tabBarController:didSelectViewController:
If you're using UINavigationController then the corresponding delegate protocol is UINavigationControllerDelegate and the method:
– navigationController:didShowViewController:animated:

Related

viewDidLoad in UITextView subclass?

Cocoa/Objective-C noob here.
I'm working on a simple app to learn some more about iOS development, and am struggling to see how my subclass of UITextView has it's viewDidLoad method called.
I am subclassing UITextView to CMTextView.
Using storyboard, I have a CMTextView in the window.
In CMTextView.m, I have the following:
#import "CMTextView.h"
#interface UITextView ()
- (id)styleString;
#end
#implementation CMTextView
- (id)styleString {
return [[super styleString] stringByAppendingString:#"; line-height: 1.1em"];
}
- (void)viewDidLoad {
NSLog(#"LOADED!"); // not doing anything...
}
I'm not doing anything fancy to add this as a subview of my window, but I thought the storyboard did that for me?
Does anyone have any advice?
The above answers are correct if you manually initialize the UITextView. If loading them from a nib, you need to override the -awakeFromNib method.
-(void)awakeFromNib
{
[super awakeFromNib]; // Don't forget to call super
//Do more intitialization here
}
If you want to handle the resizing also override the -layoutSubviews method
viewDidLoad is a method in UIViewController not UIView/UITextView
if you want to do any initialize then put it in initWithFrame:
viewDidLoad is a UIViewController method (see here).
UIKit ensures that viewDidLoad is called at appropriate times when you instantiate a view controller's view, but it has no role to play in a UIView like UITextView.
Usually, you prepare your view at initWithFrame time.
A view can never have the method viewDidLoad.
Some methods are tethered only to the viewcontroller and viewDidLoad is one of them.
The method constructors for views would be
-(id)init;
-(id)initWithFrame;

tabBarController:shouldSelectViewController: not being called when delegate is set

I think I've done my homework here.
I want my app delegate to be the delegate for my UITabBarController.
Using IB, I've connected UITabBarController's delegate to my Application Delegate.
App Delegate Header file is:
#interface MyAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
The delegate method I'm trying to implement is:
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
NSLog(#"shouldSelectViewController called.");
// do some stuff with viewController
return YES;
}
My app delegate has an outlet to the UITabBarController that's connected in IB. When I do this:
NSLog(#"tab bar controller delegate is %#", self.tabBarController.delegate);
I get a good result such as tab bar controller delegate is <MyAppDelegate: 0x6e86a30>.
What am I missing?
Just write this code. Usually in viewDidLoad().
self.tabBarController.delegate = self;
If the current controller is a UITabBarController then:
self.delegate = self
Ok, found the solution. I had some old code in my RootViewController that set up this controller as the delegate. No delegate methods were implemented on the RootViewController, so it appeared as if nothing was happening. Because the RootViewController is set as delegate AFTER MyAppDelegate, the delegate was actually set to the RootViewController.
So the lesson is double-check your code to make sure some other object isn't also being set as the delegate.

How to correctly integrate InAppSettingsKit with Storyboard in a TabBar?

I have been trying for a while now, but I can't figure out how to integrate InAppSettingsKit in an App, that uses Storyboard and a TabBar.
I've got my tab bar defined in a Storyboard, now I want one tab to have this InAppSettingsKit as the root view. Is this possible after all?
Thanks everyone.
Well, after trying various things, I figured out, that my problem actually was, that I put all the IASK-stuff into a static library (and I had no Settings Bundle). After moving all the code and nibs to the same project as the MainStoryboard, it worked by adding a TableView Controller to my storyboard and settings its custom class to IASKAppSettingsViewController.
Alternatively, if you want button handlers and other custom code, do following:
Create a class derived from UITableViewController
Modify the header file to derive from IASKAppSettingsViewController
<IASKSettingsDelegate> Remove all methods but the initWithCoder and the
settingsViewControllerDidEnd protocol (or make calls to super). This
is so that the default UITableVC code doesn't override IASK
functionality. Be sure to stick self.delegate = self; into the
initWithCoder to get the buttons to work.
//SettingsViewController.h
#import "IASKAppSettingsViewController.h"
#interface SettingsViewController : IASKAppSettingsViewController <IASKSettingsDelegate>
#end
//SettingsViewController.m
// ...
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.delegate = self;
}
return self;
}
#pragma mark -
#pragma mark IASKAppSettingsViewControllerDelegate protocol
- (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController*)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
Set custom class of the table view in storyboard to
your class

Parent View Controller and Model View Controller dismissal detection not working

I have a UIViewController called ShowListViewController that uses a Modal View Controller to push another view onto the stack:
AddShowViewController *addShowViewController = [[AddShowViewController alloc] init];
[addShowViewController setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self presentModalViewController:addShowViewController animated:YES];
I would then like to call my method populateTableData of the ShowListViewController class when the addShowViewController disappears.
I would think that the answer found here would work, but it doesn't. My method populateTableData is not detected as an optional method to use.
Essentially my questions is: How do I detect when a Modal View Controller disappears so as to call a method within the class that pushed it on the stack?
This may not be a best solution, but can do what you want at this time.
In your showlistcontroller add an instance variable like
BOOL pushedView;
#implementation ShowListViewController
and before you do the modal presentation set its values as YES like
pushedView = YES;
[self.navigationController presentModalViewController:popView animated:YES];
in the viewWillAppear of ShowListViewController you can detect whether it is appearing because pop getting dismissed or not like
if (pushedView) {
NSLog(#"Do things you would like to on pop dismissal");
pushedView = NO;
}
I think you would like something like this.
You make a delegate inside ur modalVC like this:
#protocol ModalViewDelegate <NSObject>
- (void)didDismissModalView;
#end
and implement it in your MainVC like this:
#interface MainViewController : UIViewController <ModalViewDelegate>
{
Then u will make a delegate property in your modalVC like this:
#interface ModalShizzle : UIViewController
{
id<ModalViewDelegate> dismissDelegate;
}
You set the dismissDelegate of your ModalVC to your MainVC and then you make the delegate method. Before you dismiss it however you will call the ModalVC to do one last thing. (which is populate your table). You will call for the data inside your MainVC and then do whatever you feel like it, just before you dismissed your modalVC.
-(void)didDismissModalView
{
//call ModalVC data here...
//then do something with that data. set it to a property inside this MainVC or call a method with it.
//method/data from modalVC is called here and now u can safely dismiss modalVC
[self dismissModalViewControllerAnimated:YES];
}
Hope it helps ;)
OK so it appears that in Apple's template for Utility App's they ignore what the docs for [UIViewController][1] say and actually go out of their way to call dismissModalViewControllerAnimated: from the UIViewController that pushed the modal view onto screen.
The basic idea in your case will be
Define a protocol for AddShowViewControllerDelegate
Make ShowListViewController implement this protocol
Call a method on the delegate to ask it to dimiss the modal view controller
For a full example just create a new project with Utility template and look at the source for FlipsideViewController and MainViewController
Here is an example adapted for your needs:
AddShowViewController.h
#class AddShowViewController;
#protocol AddShowViewControllerDelegate
- (void)addShowViewControllerDidFinish:(AddShowViewController *)controller;
#end
#interface AddShowViewController : UIViewController
#property (nonatomic, assign) id <AddShowViewControllerDelegate> delegate;
- (IBAction)done:(id)sender;
#end
AddShowViewController.m
- (IBAction)done:(id)sender
{
[self.delegate addShowViewControllerDidFinish:self];
}
ShowListViewController.h
#interface ShowListViewController : UIViewController <AddShowViewControllerDelegate>
{
...
}
ShowListViewController.m
- (void)addShowViewControllerDidFinish:(AddShowViewController *)controller
{
[self dismissModalViewControllerAnimated:YES];
[self populateTableData];
}

UIView notification when modal UIImagePickerController is dismissed?

Is there a way to call code when a modal view is finished dismissing?
EDIT:
I'm sorry, I didn't clarify earlier. I'm trying to dismiss a UIImagePickerController and then show a MFMailComposeViewController and attach the image data to the email. When I try to call
[self presentModalViewController: mailController]
right after
[self dismissModalViewController];
I get errors and such.
You use a delegate pattern for the modal view to inform whoever presented it when it's finished.
MyModalViewController.h:
#protocol MyModalViewControllerDelegate;
#interface MyModalViewController : UIViewController
{
id<MyModalViewControllerDelegate> delegate;
}
#property (nonatomic, assign) id<MyModalViewControllerDelegate> delegate;
#end
#protocol MyModalViewControllerDelegate
- (void)myModalViewControllerFinished:(MyModalViewController*)myModalViewController;
#end
MyModalViewController.m:
#synthesize delegate;
// Call this method when the modal view is finished
- (void)dismissSelf
{
[delegate myModalViewControllerFinished:self];
}
ParentViewController.h:
#import "MyModalViewController.h"
#interface ParentViewController : UIViewController <MyModalViewControllerDelegate>
{
}
ParentViewController.m:
- (void)presentMyModalViewController
{
MyModalViewController* myModalViewController = [[MyModalViewController alloc] initWithNibName:#"MyModalView" bundle:nil];
myModalViewController.delegate = self;
[self presentModalViewController:myModalViewController animated:YES];
[myModalViewController release];
}
- (void)myModalViewControllerFinished:(MyModalViewController*)myModalViewController
{
[self dismissModalViewControllerAnimated:YES];
}
EDIT:
I haven't used UIImagePickerController, but looking at the docs, it looks like you already have most of the code done for you, as there is an existing UIImagePickerControllerDelegate class that has three different "dismissal" delegate callbacks (although one is deprecated). So you should make your ParentViewController class (whatever that is) implement the UIImagePickerControllerDelegate pattern and then implement those methods. While each method will do something different (since you have to handle when the user actually selects an image, or if they cancel), they each will do the same thing at the end: call dismissModalViewControllerAnimated: to dismiss the picker.
You have to dismiss the modalViewController somehow right? Either a UIButton, or by code:
- (void)dismissModalViewControllerAnimated:(BOOL)animated
In the IBAction (e.g. delegate) for the UIButton or in the method above, call whatever code you want.
I don't think there is a specific notification yet can subscribe to, to know when dismiss animation is done,...BUT. You can implement viewDidAppear: in the view controller that presented the modal view. This is what I do, when I use the (to UIImagePickerController quite similar) ABPeoplePickerNavigationController.
In the callback from people picker, I remember the person tapped in the picker on an instance variable, like this:
- (void)callbackFromModalView:(id)dataFromModalView {
// remember dataFromModalView as I need it when dismissed
self.dataFromModalView = dataFromModalView;
// now initiate dismissal
[self dismissModalViewControllerAnimated:YES];
}
then, in your view controller, implement this:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.dataFromModalView) {
//...present now view here
// don't forget to reset this one
self.dataFromModalView = nil;
}
}
in effect, you are using the combination of viewWillAppear: and the dataFromModalView property as the "notification about modal view dismissed".