Dismiss popover using UIbutton - iphone

I can't figure out why it doesn't work as it should when I try to dismiss a popover by clicking on a UIButton which itself is on a the popover to be dismissed, my project crashes...
- (IBAction) cancelButton: (id) sender{
//[self dismissPopoverAnimated:YES];
}
Above is my code for my UIButton

Dont dismiss the popover from within its self. Make a protocol that sends a message to its delegate to then dismiss it. For example, your popover view controller might look like this..
// MyPopoverViewController.h
#protocol MyPopoverDelegate <NSObject>
-(void)didClickCancelButton;
#end
#interface MyPopoverViewController : UIViewController {
}
#property (nonatomic, assign) id<MyPopoverDelegate> delegate;
-(IBAction)cancelButton;
#end
// MyPopoverViewController.m
#import "MyPopoverViewController.h"
#implementation MyPopoverViewController
#synthesize delegate;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
-(IBAction)cancelButton {
[self.delegate didClickCancelButton];
}
#pragma mark -
#pragma mark Rotation support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}
#pragma mark -
#pragma mark Memory Management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
And then you could use..
// ClassImplementingPopoverController.h
#import <UIKit/UIKit.h>
#import "MyPopoverViewController.h"
#interface ClassImplementingPopoverController : UIViewController <UIPopoverControllerDelegate, MyPopoverDelegate> {
UIPopoverController *myPopoverController;
}
#property (nonatomic, retain) UIPopoverController *myPopoverController;
#end
// ClassImplementingPopoverController.m
#import "ClassImplementingPopoverController.h"
#import "MyPopoverViewController.h"
#implementation ClassImplementingPopoverController
#synthesize myPopoverController;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return YES;
}
#pragma mark -
#pragma mark MyPopover delegate
-(void)didClickCancelButton {
if ([myPopoverController isPopoverVisible]) {
[myPopoverController dismissPopoverAnimated:YES];
[myPopoverController release];
}
}
#pragma mark -
#pragma mark UIPopoverController delegate
-(void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
if (popoverController == myPopoverController) {
[myPopoverController release];
}
}
/* Use something like this to create your popover, just make sure you set the delegate to self so you can receive the messages
NSLog(#"Displaying Popover!");
MyPopoverViewController *detailViewController = [[MyPopoverViewController alloc] initWithNibName:#"MyPopoverViewController" bundle:nil];
[detailViewController setDelegate:self];
// Pass the selected object to the new view controller.
myPopoverController = [[UIPopoverController alloc] initWithContentViewController:detailViewController];
[detailViewController release];
myPopoverController.popoverContentSize = CGSizeMake(500.0, 150.0);
[myPopoverController setDelegate:self];
*/
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
self.myPopoverController = nil;
}
- (void)dealloc {
[myPopoverController release];
[super dealloc];
}
#end

you can use KVC accessing "popoverController" like
[self valueForKey:#"popoverController"]
But it is potentially rejected by AppStore if they detect your code is using their's "private API".

dismissPopoverAnimated is a property on the PopoverController itself, not your custom VC. You are showing an IBAction on 'self', which suggests you are inside your own class here. (Please post more surrounding code if that isn't correct.)
A VC can't get to its enclosing popover directly; you just need to keep a reference to it in the VC that created it so you can hit it with dismiss from there.
You can dismiss a Popover from inside itself, that doesn't crash.

Related

Give out a NSMutableArray on a texView on another Viewcontroller in objective-C?

I try to save numbers from a textfield on one viewController in a NSMutableArray when I press a button on this viewContoller. (this is working now)
Then i want the numbers give out on a textview which is on a secondViewController but this dont work. When i want to give out the array on the first Viewcontroller it work fine.
Also i cant erase the NSMutableArray with a button on the SecondviewController.
The SecondviewController have the same class like the viewController.
Can someone show me how i can give out an array on a seconviewcontroller?
Hallo,
at the moment i have this:
//ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
NSMutableArray *textViewArray;
}
#property (strong, nonatomic) IBOutlet UITextField *textLable2;
#property (strong, nonatomic) IBOutlet UITextField *textLable1;
- (IBAction)setArrayWithCurrentNumber:(id)sender;
- (IBAction)returnToTextfield:(id)sender;
#end
//this the .m file:
#import "ViewController.h"
#implementation ViewController
#synthesize textLable2;
#synthesize textLable1;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
textViewArray = [[NSMutableArray alloc]init];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setTextLable2:nil];
[self setTextLable1:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)setArrayWithCurrentNumber:(id)sender
{
NSString *string1 = self.textLable1.text;
[textViewArray addObject:string1];
NSMutableArray *array = [NSMutableArray arrayWithArray:textViewArray];
NSString *string2 = [array componentsJoinedByString:#" "];
self.textLable2.text = [NSString stringWithString:string2];
NSLog(#"%#",textViewArray);
}
- (IBAction)returnToTextfield:(id)sender
{
[textLable1 resignFirstResponder];
[textLable2 resignFirstResponder];
}
#end
If you're calling the second view controller from the first one you could set a property on the second one to hold the NSMutableArray or just send it on the initializer.
something like:
- (id)initWithArray:(NSMutableArray *)array {
if (self = [super init]) {
myArray = [array copy];
}
return self;
}
assuming your second view controller has declared NSMutableArray * myArray;
Edit: Adding some more code in here...
// I'll assume you use some kind of UINavigationController to show your content
- (void)showSecondViewController {
SecondViewController * vc = [[[SecondViewController alloc] initWithArray:yourMutableArray] autorelease];
[self.navigationController pushViewController:vc];
}

Application tried to push a nil view controller on target <UINavigationController

In my Iphone app I have this pb :Application tried to push a nil view controller on target <UINavigationController:
I have a view controller that contains a tableview and I want that if one row is selected an other view controller to be displayed.
Here is my code :
in RecherchePartenaireViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row==3){
NSLog(#"RecherchePartenaireDistanceViewController...");
recherchePartenaireDistanceViewController = [[RecherchePartenaireDistanceViewController alloc] init];
self.recherchePartenaireDistanceViewController=recherchePartenaireDistanceViewController.recherchePartenaireViewController;
[self.navigationController pushViewController:recherchePartenaireDistanceViewController animated:YES];
[recherchePartenaireDistanceViewController release];
}
}
In RecherchePartenaireDistanceViewController.h :
#class RecherchePartenaireViewController;
#interface RecherchePartenaireDistanceViewController : UIViewController {
RecherchePartenaireViewController *recherchePartenaireViewController;
}
#property (nonatomic, retain) IBOutlet RecherchePartenaireViewController *recherchePartenaireViewController;
#end
and in RecherchePartenaireDistanceViewController.m
#import "RecherchePartenaireDistanceViewController.h"
#import "RecherchePartenaireViewController.h"
#implementation RecherchePartenaireDistanceViewController
#synthesize recherchePartenaireViewController;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
[recherchePartenaireViewController release];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Where is the problem? I really can't see it. Please heeelp....
Try to use this:
- (void)dealloc
{
[recherchePartenaireViewController release];
[super dealloc];
}
instead of
- (void)dealloc
{
[super dealloc];
[recherchePartenaireViewController release];
}
I think I see what you're doing but I don't understand what you're trying to achieve! You have a ViewController that contains another view controller?
i.e. RecherchePartenaireDistanceViewController contains a RecherchePartenaireViewController
I assume that as it's an IBOutlet you're populating it using a xib file.
The only thing I can think of is that something is going wrong with the creation of your RecherchePartenaireDistanceViewController in the xib file.
What do you see in the console if you do this :
NSLog(#"controller : %#", recherchePartenaireDistanceViewController);
just before adding it to the navigation controller?
PS
What's the purpose of this line?
self.recherchePartenaireDistanceViewController=recherchePartenaireDistanceViewController.recherchePartenaireViewController;
if RecherchePartenaireDistanceViewController is with xib interface than use following statement while initializing,
recherchePartenaireDistanceViewController = [[RecherchePartenaireDistanceViewController alloc] initWithNibName:#"RecherchePartenaireDistanceViewController" bundle:nil];
than push it to navigation controller.

Showing ads on every view automatically in iPhone

I'm implementing Mobclix in my app, and when following the instructions, it tells us to properly release and dealloc the adview. It also tells us that when the view appears, you should call refreshAds and when it disappears you should pause refresh ads:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.adView resumeAdAutoRefresh];
}

- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.adView pauseAdAutoRefresh];
}
#implementation RootViewController
- (void)viewDidUnload {
[self.adView cancelAd];
self.adView.delegate = nil;
self.adView = nil;
}
- (void)dealloc {
[self.adView cancelAd];
self.adView.delegate = nil;
self.adView = nil;
[super dealloc];
}
#end
My question is that I have a lot of view controllers, so it would be inconvenient to implement these things on each view. Is there anyway I can call these methods in one place and have it work for all views?
What you can do is subclass UIViewController and have all your viewControllers to inherit these things.
So basically you could have AdsViewController.h wich will look like
#import <Foundation/Foundation.h?
#interface AdsViewController: UIViewController {
}
#property (nonatomic, retain) <#AdsViewType#> *adsView;
#end
and your AdsViewController.m will have to look pretty much like this
#import "AdsViewController.h"
#implementation AdsViewController
#synthesize adsView = _adsView;
- (id)init {
self = [super init];
if (self) {
_adsView = [[<#AdsViewType#> alloc] init];
_adsView.delegate = self;
}
return self;
}
- (void)viewDidUnload {
[self.adView cancelAd];
self.adView = nil;
[super viewDidUnload];
}
- (void)dealloc {
[self.adView cancelAd];
self.adsView = nil;
[super dealloc];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.adView resumeAdAutoRefresh];
}

- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.adView pauseAdAutoRefresh];
}
#end
After this have all your viewControllers to subclass this instead of UIViewController. Hope this helps.

Making Progress View Visible

I'm working on a very simple iOS app to get me started programming. It's a tab based application, so there is a MainWindow.xib along with a FirstView.xib and SecondView.xib. All of this is happening in the first view. I want to add a Progress bar to the First View, and when I added the object it attached itself to FirstView.xib and shows up and lets me move it around. To test, the alpha is set at 1.00 and the progress is set at 0.5. Regardless of this, it doesn't show up no matter what I do. What am I doing wrong?
AppDelegate.m:
#synthesize window=_window;
#synthesize tabBarController=_tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Add the tab bar controller's current view as a subview of the window
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
- (void)applicationWillTerminate:(UIApplication *)application
{
}
- (void)dealloc
{
[_window release];
[_tabBarController release];
[super dealloc];
}
#end
FirstViewController.h:
#import <UIKit/UIKit.h>
NSTimer *stopWatchTimer;
NSDate *startDate;
#interface FirstViewController : UIViewController {
UILabel *label;
UILabel *stopWatchLabel;
UIProgressView *progressBar;
UIButton *topButton;
}
#property (nonatomic, retain) IBOutlet UILabel *stopWatchLabel;
#property (nonatomic, retain) IBOutlet UIProgressView *progressBar;
- (IBAction)onStartPressed:(id)sender;
- (IBAction)onStopPressed:(id)sender;
- (IBAction)onResetPressed:(id)sender;
#end
FirstViewController.m
#import "FirstViewController.h"
#implementation FirstViewController
#synthesize progressBar;
#synthesize stopWatchLabel;
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.*/
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload
{
[self setStopWatchLabel:nil];
[topButton release];
topButton = nil;
[super viewDidUnload];
// Release any[progress release];
progressBar = nil;
[progressBar release];
progressBar = nil;
[self setProgressBar:nil];
//retained subviews of the[self setProgressBar:nil];
// e.g. self.myOutlet = nil;
}
static NSInteger counter=0;
static NSInteger secs=0;
static NSInteger mins=0;
static NSInteger hrs=0;
- (void)dealloc
{
[stopWatchLabel release];
[label release];
[topButton release];
[super dealloc];
}
-(void)updateTimer {
//updates the timer }
-(void)clearTimer {
//clears the timer
}
-(void)stopTimer{
//stops the timer }
- (IBAction)onStartPressed:(id)sender {
//stopWatchLabel.text=#"Start Pressed";
progressBar.alpha=1.0;
//run timer }
- (IBAction)onStopPressed:(id)sender {
[self stopTimer];
}
- (IBAction)onResetPressed:(id)sender {
[self stopTimer];
[self clearTimer];
}
#end
There are two things you need to do with a view after it's been created: You have to add it as a subview of a visible view and set a proper frame.
Here's how to do that:
[self.view addSubview:progressBar];
progressBar.frame = CGRectMake(x, y, width, height);
EDIT: Probably completely unrelated to your question, but this is all wrong:
- (void)viewDidUnload
{
[self setStopWatchLabel:nil];
[topButton release];
topButton = nil;
[super viewDidUnload];
// Release any[progress release];
progressBar = nil;
[progressBar release];
progressBar = nil;
[self setProgressBar:nil];
//retained subviews of the[self setProgressBar:nil];
// e.g. self.myOutlet = nil;
}
You probably want it to look something like the following:
- (void)viewDidUnload
{
[super viewDidUnload];
[self setStopWatchLabel:nil];
[topButton release];
topButton = nil;
[label release];
label = nil;
self.progressBar = nil;
}
Make sure you understand what you did wrong. It's very important that you get this right or your app will leak and/or crash.
The rest of your code doesn't really do anything. You seem to be doing everything in IB, so I guess that's where your problem is.

UIImageView subclass with CGRectIntersectsRect - help!

The title of this question should be pretty self explanatory. I am making an app that involves multiple UIImageViews that serve the same purpose. They are merely different sizes. Anyway, I decided that the best solution was to make UIImageView subclasses, link the subcalsses in IB, and work from there. My code should explain this better -
#define kPausedStatePaused 1
#define kPausedStatePlay 2
#import "Game.h"
#import "ScoreSystem.h"
#interface Doctor : UIImageView
{
}
#end
#interface Ground : UIImageView
{
}
#end
#interface Wall : UIImageView
{
}
#end
#interface Electric_Wire : UIImageView
{
}
#end
#implementation Game
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
- (IBAction)pause {
UIAlertView *pause = [[UIAlertView alloc] initWithTitle:#"Pause" message:nil delegate:self cancelButtonTitle:#"Quit" otherButtonTitles:#"Play", nil];
[pause show];
[pause release];
pauseint = kPausedStatePaused;
}
- (void)viewDidAppear {
pauseint = kPausedStatePlay;
}
- (void)loop {
Doctor *doctorview;
Ground *groundview;
if (CGRectIntersectsRect(doctorview, groundview)) {
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if ([alertView.title isEqual:#"Pause"]) {
if(buttonIndex == 0)
[self dismissModalViewControllerAnimated:YES];
pauseint = kPausedStatePlay;
}
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
Unsurprisingly, Xcode gave me an "incompatible type for CGRectIntersectsRect" error.
You must pass view's frame, not the view's themselves to that function:
CGRectIntersectsRect(doctorview.frame, groundview.frame)