I create a UIViewController with a button on it. The button's only job is to create a window for drawing some rectangles. (I've taken some code from "QuartzDemo" from Apple's example applications.) Objective C is really giving me fits...
When I try this, nothing happens.
Here's the code for the button:
- (IBAction)startButtonAct:(id)sender
{
QuartzViewController *controller;
NSLog(#"1");
controller = [[QuartzViewController alloc] initWithTitle:#"Dotsie"];
controller.quartzViewDelegate = [[[RectDrawing alloc] init] autorelease];
[[self navigationController] pushViewController:controller animated:YES];
// [controller release];
}
I'm honestly not sure what else anyone needs to see, but here's some of the other stuff:
#interface QuartzViewController : UIViewController
{
QuartzView *quartzView;
UIBarStyle barStyle;
UIStatusBarStyle statusStyle;
}
#protocol QuartzViewDelegate;
#interface QuartzView : UIView {
id<QuartzViewDelegate> delegate;
}
#property(assign) id<QuartzViewDelegate> delegate;
#end
#protocol QuartzViewDelegate<NSObject>
#required
// Draw contents into the given view, using the given context and bounds.
-(void)drawView:(QuartzView*)view inContext:(CGContextRef)context bounds:(CGRect)bounds;
#end
Please help -- this is driving me crazy -- I've been fighting with the same basic problem now for a week...
First, the [controller release] line should be there, uncommented. I'm sure you just disabled it for debugging.
If you insert the line:
NSLog(#"%#", [self navigationController]);
In your button action, does it log a valid controller or does it say nil? If it's nil, my guess is that this view controller wasn't properly pushed onto a navigation controller itself.
Related
so in my app delegate I am trying to present a modalViewController from a UITabBarController, by doing the following:
self.tabBarController = [[UITabBarController alloc] init];
LoginViewController* loginViewController = [[LoginViewController alloc] init];
loginViewController.delegate = self;
[self.tabBarController presentModalViewController:loginViewController animated:NO];
[loginViewController release];
and the delegate defined in the app delegate is:
- (void)userDidLogin:(LoginViewController *) loginViewController
{
NSLog(#"DELEGATE CALLED, DISMISSING");
[self.tabBarController dismissModalViewControllerAnimated:NO];
}
Here's my LoginViewController:
protocol LoginViewControllerDelegate;
#interface LoginViewController : UIViewController <MBProgressHUDDelegate>
{
id<LoginViewControllerDelegate> delegate;
}
#property (assign) id<LoginViewControllerDelegate> delegate;
#end
#protocol LoginViewControllerDelegate
- (void)userDidLogin:(LoginViewController *) loginViewController;
#end
The issue is that this (userDidLogin:(LoginViewController *) loginViewController) is never called... why is this?
I have called the following in my LoginViewController implementation and this is called
[self.delegate userDidLogin:self];
UPDATE:
I got the delegate called now. The issue now is that when I call [self.tabBarController dismissModalViewControllerAnimated:YES] it doesn't dismiss the modal view controller.
You didn't post any code from LoginViewController, but within that class's code you need to add the following lines when you are ready to dismiss it (perhaps when the user clicks the "Login" button and the login is successful).
if (delegate && [delegate respondsToSelector:#selector(userDidLogin:)])
[delegate performSelector:#selector(userDidLogin:) withObject:self];
UPDATE:
I think I understand what the issue is here. According to Apple's documentation, when you call presentModalViewController:animated: the method sets the value of the "modalViewController" property of UIViewController (in this case your UITabBar). However that property only maintains a weak reference to the modalViewController. That's important because you initialize the LoginViewController, pass it in to presentModalViewController:animated: and then you release it. Since presentModalViewController:animated: is not retaining a strong reference to the LoginViewController, the UITTabBar is unable to dismiss it later on. In fact I'm surprised what you have done is not resulting in an EXC_BAD_ACCESS crash. I suggest you remove the "[loginViewController release]" statement and instead release it after you call "[self.tabBarController dismissModalViewControllerAnimated:NO]"
I'm having an issue with the dismissModalViewControllerAnimated method.
The header looks like this:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "GADBannerView.h"
#import "weatherSetUp.h"
#interface weatherPicViewController : UIViewController{
In my viewController.m file I call
-(IBAction)didClickSetting:(id)sender{
weatherSetUp *views = [[weatherSetUp alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:views animated:YES];
}
This all works fine, In my weatherSetUp file once the user has completed set up I was to dismiss the modal view. I do it by calling this method in the above viewController.m file:
-(void)dismissModal{
[self.parentViewController dismissModalViewControllerAnimated:NO];
[self dismissModalViewControllerAnimated:NO];
[self dismissModalViewControllerAnimated:NO];
[self.parentViewController dismissModalViewControllerAnimated:NO];
NSLog(#"Model gone!");
}
But none of these work.
This is the header file of my weatherSetUp file:
#import <UIKit/UIKit.h>
#import "viewController.h"
#interface weatherSetUp : UIViewController
-(IBAction)didClickClose:(id)sender;
#end
And the only method I've implemented is:
-(IBAction)didClickClose:(id)sender{
NSLog(#"CLick ");
viewController *viewEr = [[viewController alloc] init];
[viewEr dismissModal];
}
All the NSLog's work when I click the button, I've searched on here and tried too the above ways of dismissing it and none of them work, any ideas?
What is going wrong is you're calling dismissModal on a random view controller rather than the object that actually has the modal controller. What you'd want to do in didClickClose: is this
[[self parentViewController] dismissModalViewControllerAnimated:NO];
Also, you shouldn't be starting your class names with lowercase characters in Cocoa. They should really be capitalised and have a prefix, eg ABCWeatherSetUp. The prefix can be whatever you want, but generally you want something based on your name, your company's name or your project's name.
insted of [self.parentViewController dismissModalViewControllerAnimated:NO];
write this [self dismissModalViewControllerAnimated:NO];
Your viewEr is not the same viewController which you are trying to close, because you are creating the new object of your viewContoller.
you can create a viewContoller properties and in your viewController class file
weatherSetup.viewController = self.parentViewController;
NOTE: do not use viewContoller as a ivar, use different may name.
I have a UIViewController which shows different UIViewController sub-classes. In the main UIViewController.m, I have a sub-class called 'Home' load on app start.
Now, which the Home view loaded, I have a button which I want to use to switch to another view called 'PreGameInfo'. I'm trying to use the code below:
- (IBAction)showPreGameInfo:(id)sender {
[self.view insertSubview:preGameInfo.view atIndex:0];
}
It doesn't work, and I know it's because the 'self.view' needs to refer to the main UIViewController rather than the self of the 'Home' view. Does anyone know how to insertSubView to the main UIViewController when using a UIButton whilst in a SubView???
Thank you!
You can use a delagate. It very easy
So implement this in your information view controller;
In the InformationViewController.h
#protocol InformationViewControllerDelegate;
#interface InformationViewController : UIViewController {
id <InformationViewControllerDelegate> delegate;
}
#property (nonatomic, assign) id <InformationViewControllerDelegate> delegate;
- (IBAction)returnBack:(id)sender;
#end
#protocol InformationViewControllerDelegate
- (void)InformationViewControllerDidFinish:(InformationViewController *)controller;
#end
in the InformationViewController.m
- (IBAction)returnBack:(id)sender {
[self.delegate InformationViewControllerDidFinish:self];
}
And use the delegate in any view controller you need it like this :
In the HomeViewController.h
#import "InformationViewController.h"
#interface HomeViewController : UIViewController <InformationViewControllerDelegate> {
}
Write the method to change the view from Home view to Information view
- (IBAction)goToInformationView:(id)sender;
In the HomeViewController.m
- (IBAction)goToInformationView:(id)sender {
InformationViewController *controller = [[InformationViewController alloc] initWithNibName:nil bundle:nil];
controller.delegate = self;
// You can chose the transition you want here (they are 4 see UIModalTransitionStyle)
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
And the last but not least the delegate method it inform the HomeViewController when the InformationViewController had finished
- (void)InformationViewControllerDidFinish:(InformationViewController *)controller {
[self dismissModalViewControllerAnimated:YES];
}
I hope it helps
- (IBAction)showPreGameInfo:(id)sender {
[superview insertSubview:preGameInfo.view atIndex:0];
}
Does this code work?
[self.parentViewController.view addSubview:myView];
Just do it in the modalView:
[self presentModalViewController:preGameInfo animated:YES]
or you can do something like this...
This line will add your new view to windows rootViewControllers view
[self.view.window.rootViewController.view addSubview:preGameInfo.view];
I'm stuck with an issue.... Please help!
I have a navigation controller project. From the root controller I am pushing a view onto the stack that has some info and 2 buttons (YES, NO). (it can't be an AlertView). If they press the YES button, I call a method on the parent view (using a delegate method) and pop the view from the stack. The method on the parent pushes a new view onto the stack. I assumed the parent method would remain in memory after the deallocation of the child view because the method exists on the parent, but when the child is deallocated it also deallocates everything created inside the method on the parent. Does anyone have a solution for responding to events that happen on a child view in a parent view that will remain after the child is deallocated?
Thanks!
in header file:
#import <UIKit/UIKit.h>
#protocol decrementDelegate;
#interface decrement : UIViewController {
int currentCount;
IBOutlet UILabel *countLabel;
id <decrementDelegate> delegate;
}
#property (nonatomic, assign) id <decrementDelegate> delegate;
#end
#protocol decrementDelegate <NSObject>
-(void)decrementControllerDidFinish:(decrement *)controller
withString:(NSString *)stringValue;
#end
in implementation file:
[self.delegate decrementControllerDidFinish:self
withString:countLabel.text];
[self.navigationController popViewControllerAnimated:YES];
caller:
-(void)decrementControllerDidFinish:(decrement *)controller
withString:(NSString *)stringValue {
// Show our details
myNewChildController *viewController = [[myNewChildController alloc]
initWithNibName:#"myNewChildController" bundle:nil];
viewController.delegate = self;
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
}
Using non-delegate and just calling a method on the parent:
caller:
mySummary *parent = [self.navigationController.viewControllers objectAtIndex:0];
[mySummary setMyAllowOnParent:#"Allowed"];
[self.navigationController popViewControllerAnimated:YES];
parent:
-(void)setMyAllowOnParent:(NSString *)aAllow {
newView *viewController = [[newView alloc] initWithNibName:#"newView" bundle:nil];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
}
newView crashes with deallocated error when caller view is deallocated. Does anyone have an idea how to resolve this issue?
How did you create your delegate? You didn't accidentally used retain instead of assign (assuming you use a property to access it)? Because if you used retain, this might have caused the issue.
By the way, you mention something about a UIAlertView that cannot be used, which leads me to think that you created a view with a similar design as a UIAlertView. Perhaps the following link might be useful:
how can i make popup login window similar as on istore in objective-C/cocoa-touch
I have a small doubt. I have a NSObject class where I am trying to display an alert view. So after the alert view is displayed when I tap on OK button I want to push a navigation controller onto the stack. Can I push a navigation controller from general NSObject class? Please let me know guys..thanks for your time..
This is the code..
- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex{
SettingsViewController *homeView = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
[self.navigationController pushViewController:homeView animated:NO];
[homeView release];
}
I am creating a property called navigationController of type UINavigationController and when I catch the error I am displaying an alert view and I am using above method to push the view controller but it doesn't work..
Yes and no... depending on how you have your application set up. To push views onto the navigation stack you need to have a navigation controller.
Does your NSObject have access to this navigation controller - you might have to set up a delegate method that gets called from your delegate view when the alert view delegate gets called in your NSObject.
I'm just wondering why you're displaying a UIAlertView in an NSObject, why aren't you displaying it in a UIView or a UIViewController?
CustomObject.h
#protocol CustomObjectDelegate<NSObject>
#optional
- (void)customObjectAlertViewDidClickOk;
#end
#interface CustomObject : NSObject <UIAlertViewDelegate>{
id<CustomObjectDelegate> delegate;
}
#property (nonatomic, assign) id<CustomObjectDelegate> delegate;
#end;
CustomObject.m
#synthesize delegate;
// then put this:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
[delegate customObjectAlertViewDidClickOk];
}
Then your ViewController .h file needs to include the custom object and assign the delegate methods:
#include "CustomObject.h"
#interface MyViewController : UIViewController <CustomObjectDelegate> {
}
#end
and the .m viewDidLoad (or similar):
- (void)viewDidLoad{
CustomObject *obj = [[CustomObject alloc] init];
[obj setDelegate:self];
}
- (void)customObjectAlertViewDidClickOk{
AnotherViewController *page = [[AnotherViewController alloc] initWithNibName:nil bundles:nil];
[self.navigationController pushViewController:page];
}
Thats how I would do it - given I'm not too sure i understand quite what you're asking. :) thats all off the top of my head as well - so don't take it letter for letter, but you have the basis there to start off with. You can build on it. Look up #protocols and delegate methods, its all in there. :)