How to Change view(XIB) after imagePickerController:didFinishPickingMediaWithInfo? - objective-c

I am new on iphone and objective-c development.
I want to know how i can change the view (XIB File) after the camera takes a picture.
Can anyone help me or share some code? I am searching for this since a week :(
After finishing the app, i am ready to share my project and/or make a tutorial.
Infos about my App: i want to scan barcodes and save the barcodes in my app.
For scanning barcodes iam using the ZBarSDK.
I hava a TabBarController, on the first Tab, i can open the camera.
After the scan process i want to jump to the second tab (another XIB File) and show the results.
Thanks for any help.
Here my code of the first tab (ScanCodeViewController):
.h
#import < UIKit/UIKit.h >
#class OutPutCodeViewController;
#interface ScanCodeViewController : UIViewController <ZBarReaderDelegate> {
IBOutlet UIImageView *img;
OutPutCodeViewController *output;
}
#property (nonatomic, retain) IBOutlet UIImageView *img;
#property (nonatomic, retain) OutPutCodeViewController *output;
- (IBAction) scanButton;
#end
.m
#import "ScanCodeViewController.h"
#implementation ScanCodeViewController
#synthesize img;
#synthesize output;
- (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 {
[img release];
[super dealloc];
}
- (IBAction) scanButton {
NSLog(#"Scanbutton wurde geklickt!");
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
ZBarImageScanner *scanner = reader.scanner;
[scanner setSymbology: ZBAR_I25 config: ZBAR_CFG_ENABLE to: 0];
[self presentModalViewController:reader animated: YES];
[reader release];
}
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
NSLog(#"Entered imagePickerController");
// ADD: get the decode results
id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results) {
break;
}
img.image = [info objectForKey:UIImagePickerControllerOriginalImage];
[reader dismissModalViewControllerAnimated: YES];
//[self presentModalViewController:output animated:YES]; //by using this, app chrashes
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissModalViewControllerAnimated: YES];
}
#end
And here the Secong Tab (OutPutCodeViewController)
.h
#import <UIKit/UIKit.h>
#interface OutPutCodeViewController : UIViewController {
IBOutlet UIImageView *resultImage;
IBOutlet UITextField *resultText;
}
#property (nonatomic, retain) IBOutlet UIImageView *resultImage;
#property (nonatomic, retain) IBOutlet UITextField *resultText;
#end
.m
#import "OutPutCodeViewController.h"
#implementation OutPutCodeViewController
#synthesize resultImage;
#synthesize resultText;
- (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 {
[resultImage release];
[resultText release];
[super dealloc];
}
#end

Got it!
It is not possible to set more animate:YES.
Here is the sample and right code.
I hope it helps others.
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
break;
[reader dismissModalViewControllerAnimated: NO];
TableDetailViewController *tc = [[TableDetailViewController alloc] initWithNibName:#"TableDetailViewController" bundle:nil];
tc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:tc animated:YES];
[tc release];
}
brush51

In didFinishPickingMediaWithInfo you should call [self.tabBarController setSelectedIndex:1] to switch to the second tab.

Related

Create a UIPageViewController with a UITableView in each page

I have been reading things on stack overflow for quite a while now but this is my first post, only because it is the first time I have a problem that no one else seems to have fixed yet!
Ok, down to business. It should be a simple matter to put UITableViews inside a UIPageView but I am having difficulties. I have a ViewController and contentViewController. I am using .xibs instead of storyboarding. The contentViewController.xib is a Table View and the ViewController.xib is a View. I am only focusing on iPhone. The UITableView is connected to dataSource, delegate, and Referencing Outlet named theTableView.
The project builds but when I run it I get the following error message:
2013-03-17 16:14:23.026 pageApp[775:c07] *** Assertion failure in -[UITableView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2380.17/UIView.m:5776
2013-03-17 16:14:23.028 pageApp[775:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'
*** First throw call stack:
(0x1c93012 0x10d0e7e 0x1c92e78 0xb66665 0x6539f 0x10e46b0 0x228ffc0 0x228433c 0x228feaf 0x1042bd 0x4cb56 0x4b66f 0x4b589 0x4a7e4 0x4a61e 0x4b3d9 0x4e2d2 0xf899c 0x45574 0x4576f 0x45905 0x4e917 0x20eb 0x12157 0x12747 0x1394b 0x24cb5 0x25beb 0x17698 0x1beedf9 0x1beead0 0x1c08bf5 0x1c08962 0x1c39bb6 0x1c38f44 0x1c38e1b 0x1317a 0x14ffc 0x1d2d 0x1c55)
libc++abi.dylib: terminate called throwing an exception
This crashes after -(void)viewDidLoad{} in ViewController.m and I have not yet learned how to fix auto layout/ layoutSubview errors. Does anyone else know how?
I have limited experience with ios development so I am sure that I just don't have the right pieces in the right spots. I used http://www.techotopia.com/index.php/An_Example_iOS_5_iPhone_UIPageViewController_Application to get this far.
My code is as follows:
ViewController.h
#import <UIKit/UIKit.h>
#import "contentViewController.h"
#interface ViewController : UIViewController
<UIPageViewControllerDataSource>
{
UIPageViewController *pageController;
NSArray *pageContent;
}
#property (strong, nonatomic) UIPageViewController *pageController;
#property (strong, nonatomic) NSArray *pageContent;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize pageController, pageContent;
- (contentViewController *)viewControllerAtIndex:(NSUInteger)index
{
// Return the data view controller for the given index.
if (([self.pageContent count] == 0) || (index >= [self.pageContent count])) {
return nil;
}
// Create a new view controller and pass suitable data.
contentViewController *dataViewController =[[contentViewController alloc]initWithNibName:#"contentViewController"bundle:nil];
dataViewController.dataObject =[self.pageContent objectAtIndex:index];
return dataViewController;
}
- (NSUInteger)indexOfViewController:(contentViewController *)viewController
{
return [self.pageContent indexOfObject:viewController.dataObject];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = [self indexOfViewController:(contentViewController *)viewController];
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = [self indexOfViewController:(contentViewController *)viewController];
if (index == NSNotFound) {
return nil;
}
index++;
if (index == [self.pageContent count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
- (void) createContentPages
{
NSMutableArray *pageStrings = [[NSMutableArray alloc] init];
for (int i = 1; i < 4; i++)
{
NSString *contentString = [[NSString alloc]initWithFormat:#"Chapter %d \nThis is the page %d of content displayed using UIPageViewController in iOS 5.", i, i];
[pageStrings addObject:contentString];
}
pageContent = [[NSArray alloc] initWithArray:pageStrings];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self createContentPages];
self.pageController = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
pageController.dataSource = self;
[[pageController view] setFrame:[[self view] bounds]];
contentViewController *initialViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
[pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:pageController];
[[self view] addSubview:[pageController view]];
[pageController didMoveToParentViewController:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
contentViewController.h
#import <UIKit/UIKit.h>
#interface contentViewController : UIViewController
#property (strong, nonatomic) IBOutlet UITableView *theTableView;
#property (strong, nonatomic) id dataObject;
#property (strong, nonatomic) NSArray *pageContent;
#end
contentViewController.m
#import "contentViewController.h"
#interface contentViewController ()
#end
#implementation contentViewController
#synthesize theTableView, dataObject, pageContent;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void) createContentPages
{
NSMutableArray *pageStrings = [[NSMutableArray alloc] init];
for (int i = 1; i < 4; i++)
{
NSString *contentString = [[NSString alloc]initWithFormat:#"Chapter %d \nThis is the page %d of content displayed using UIPageViewController in iOS 5.", i, i];
[pageStrings addObject:contentString];
}
pageContent = [[NSArray alloc] initWithArray:pageStrings];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self createContentPages];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection (NSInteger)section
{
return 4;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath (NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [pageContent objectAtIndex:indexPath.row];
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
So if anyone could straighten me out I would appreciate it.
I was able to solve my own problem, and it seems I was just a bit mixed up.
The comment from rdelmar set me on the right track but I hooked the delegate and data source to the wrong object. I had to connect them to File's Owner in order for it to work.
In addition it seems theTableView was not necessary and when I removed that my code suddenly worked as expected.
If this isn't clear enough for an answer please tell me how I can be more specific. Thank you!

Passing value from one class to another, using #property

I have been pulling my hair out all afternoon trying to figure out why the following code will not work. All I am trying to do is pass a string, from one class to another.
In my FirstDetailViewController.h file I declare the NSString
#property(nonatomic, retain) NSString *infoForArray;
And then in my Grinding01_DetailViewController.m I try to set a value for the string
#import "Grinding01_DetailViewController.h"
#import "FirstDetailViewController.h"
#implementation Grinding01_DetailViewController
...
NSString *didLoadMessage = #"Grinding01 Loaded";
FirstDetailViewController *temp = [[FirstDetailViewController alloc] initWithNibName:#"FirstDetailView" bundle:nil];
temp.infoForArray = didLoadMessage;
[self.navigationController pushViewController:temp animated:YES];
}
When I output the infoForArray from the FirstDetailViewController.h it is null.
Any help would be appreciated, I think there's a simple step that I am missing, but I just can't see it.
EDIT: Here is the code from the FirstDetailViewController
FirstDetailViewController.h
#import <UIKit/UIKit.h>
#import "Protocols.h"
#interface FirstDetailViewController : UIViewController <SubstitutableDetailViewController> {
//for the output
IBOutlet UITextView *outputView;
UIToolbar *navigationBar;
NSMutableArray *logMessages;
}
#property (nonatomic, retain) IBOutlet UIToolbar *navigationBar;
//for incoming messages
#property(nonatomic, retain) NSString *infoForArray;
#end
FirstDetailViewController.m
#import "FirstDetailViewController.h"
#implementation FirstDetailViewController
#synthesize navigationBar, infoForArray;
-(void)viewDidLoad{
[super viewDidLoad];
//The log cannot be changed
outputView.editable = NO;
}
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidUnload {
[super viewDidUnload];
self.navigationBar = nil;
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
NSLog(#"message: %#", infoForArray);
outputView.text = infoForArray;
}
#pragma mark -
#pragma mark Managing the popover
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
// Add the popover button to the toolbar.
NSMutableArray *itemsArray = [navigationBar.items mutableCopy];
[itemsArray insertObject:barButtonItem atIndex:0];
[navigationBar setItems:itemsArray animated:NO];
[itemsArray release];
}
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {
// Remove the popover button from the toolbar.
NSMutableArray *itemsArray = [navigationBar.items mutableCopy];
[itemsArray removeObject:barButtonItem];
[navigationBar setItems:itemsArray animated:NO];
[itemsArray release];
}
#pragma mark -
#pragma mark Rotation support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
#pragma mark -
#pragma mark Memory management
- (void)dealloc {
[navigationBar release];
[super dealloc];
}
#end
It sounds like the trouble area is in in FirstDetailViewController. I would suggest posting the code for that so we can see what's going on.
my guess is you are checking for infoForArray somewhere in the instantiation process of FirstDetailViewController, which occurs before you set temp.infoForArray = didLoadMessage.
Just for reference, if you check for infoForArray in viewDidLoad that will be too early. viewDidLoad is triggered when the view is put into memory. What you want is viewDidAppear, which you may have to add yourself

How to pass Arrays to a UIPickerView from one class to another?

Bah. I've pulled my hair out over this problem for the past couple days now, but I know I must be overlooking the obvious. I've made my PickerViewController(.h./m) and PickerViewAppDelegate(.h/.m) files and they run fine as a standalone program, but I would like to have the picker pop up after a procedureal event occurs in my "helloworld.m" file. I can get the picker to show up, but I cannot for the life of me figure out how to populate it so that it isn't blank. I THINK I've done everything right up until I try to pass my array to my pickerview object. What am I doing wrong?
PickerViewController.h
#import <UIKit/UIKit.h>
#interface PickerViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate> {
IBOutlet UIPickerView *pickerView;
NSMutableArray *scrollerData;
}
#property (nonatomic, retain) IBOutlet UIPickerView *pickerView;
#property (nonatomic, retain) NSMutableArray *scrollerData;
-(void)setScrollerData:(NSMutableArray *)array;
#end
PickerViewController.m
#import "PickerViewController.h"
#implementation PickerViewController
#synthesize pickerView, scrollerData;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.pickerView.delegate = self;
self.pickerView.dataSource = self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
// [arrayColors release];
[super dealloc];
}
-(void)setScrollerData:(NSMutableArray *)array
{
//[self.scrollerData arrayByAddingObjectsFromArray:array];
scrollerData = array;
}
#pragma mark -
#pragma mark Picker View Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
return [scrollerData count];
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [scrollerData objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSLog(#"Selected Number: %#. Index of selected numbers: %i", [scrollerData objectAtIndex:row], row);
}
PickerViewAppDelegate.h
#import <UIKit/UIKit.h>
#class PickerViewController;
#interface PickerViewAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
PickerViewController *pvController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
PickerViewAppDelegate.m
#import "PickerViewAppDelegate.h"
#import "PickerViewController.h"
#implementation PickerViewAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
pvController = [[PickerViewController alloc] initWithNibName:#"PickerView" bundle:[NSBundle mainBundle]];
[window addSubview:pvController.view];
// Override point for customization after application launch
[window makeKeyAndVisible];
}
- (void)dealloc {
[pvController release];
[window release];
[super dealloc];
}
#end
Helloworld.m
...
UIView* view = [[CCDirector sharedDirector] openGLView];
UIPickerView *pickerView=[[UIPickerView alloc] init];
pickerView.frame=CGRectMake(100,100, 200, 200);
NSMutableArray *arrayNumbers = [[NSMutableArray alloc] init];
[arrayNumbers addObject:#"30"];
[arrayNumbers addObject:#"31"];
[arrayNumbers addObject:#"32"];
[arrayNumbers addObject:#"33"];
[arrayNumbers addObject:#"34"];
[arrayNumbers addObject:#"35"];
[arrayNumbers addObject:#"36"];
[pickerView setscrollerData: arrayNumbers];//Should I be calling pickerView here or something else?
[view addSubview: pickerView];
pickerView.hidden=NO;
...
You have overridden the setter method generated by #synthesize in PickerViewController, so you are no longer retaining it.
Then, you are calling setScrollerData on your pickerView (this should be giving you a warning or crashing since pickerView doesn't respond to that method).
You are not setting PickerViewController as the delegate or datasource of your picker view in helloworld.m.
I can't see where your hello world code fits in. It seems to be adding a new picker view rather than using the one from the xib of PickerViewController. You should be instantiating pickerviewcontroller from your hello world and adding its .view as a subview or presenting it as a modal view controller rather than setting up a new picker view. You can then pass your array to the instance of pickerviewcontroller. Note though that it is not standard to have a separate view controller for what is essentially a subview, though I don't have much knowledge of cocos2d so I don't know if this is normal when using that framework.
Well, i think you should just pass the array from HelloWorld class to PickerViewController class using property/synthesize.

Works on iPad Simulator but crashes on iPad

Hi I am trying to develop a new app on the ipad. I am using a spitTableView and adding a ModalPresentationPage to the view. This works perfectly on the xcode iPad sim but crashes on my iPad. just so you know I am using xcode 5BATA and running IOS 5 on my iPad.
here is my code
DetailViewController.h
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController <UISplitViewControllerDelegate>{
}
-(IBAction)loadView:(id)sender;
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#property (strong, nonatomic) IBOutlet UIToolbar *toolbar;
#end
DetailViewController.m
#import "DetailViewController.h"
#import "ModalViewController.h"
#import "RootViewController.h"
#interface DetailViewController ()
#property (strong, nonatomic) UIPopoverController *popoverController;
- (void)configureView;
#end
#implementation DetailViewController
#synthesize detailItem = _detailItem;
#synthesize detailDescriptionLabel = _detailDescriptionLabel;
#synthesize toolbar = _toolbar;
#synthesize popoverController = _myPopoverController;
-(IBAction)loadView:(id)sender{
ModalViewController *mvc = [[ModalViewController alloc]initWithNibName:#"modalViewController"bundle:nil];
mvc.modalPresentationStyle = UIModalPresentationPageSheet;
mvc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:mvc animated:YES];
}
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
}
return self;
}
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
if (self.popoverController != nil) {
[self.popoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
}
}
- (void)didReceiveMemoryWarning
{
[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, typically from a nib.
[self configureView];
self.splitViewController.delegate = self;
}
- (void)viewDidUnload
{
[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 YES;
}
#pragma mark - Split view
- (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController: (UIPopoverController *)pc
{
barButtonItem.title = #"Master";
NSMutableArray *items = [[self.toolbar items] mutableCopy];
[items insertObject:barButtonItem atIndex:0];
[self.toolbar setItems:items animated:YES];
self.popoverController = pc;
}
- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
// Called when the view is shown again in the split view, invalidating the button and popover controller.
NSMutableArray *items = [[self.toolbar items] mutableCopy];
[items removeObjectAtIndex:0];
[self.toolbar setItems:items animated:YES];
self.popoverController = nil;
}
#end
Parts not under NDA :-
You are leaking items in both the split view delegate methods.
Are you sure the XIB name is modalViewController? There could a problem of it being case sensitive on the device.

EXC_BAD_ACCESS when I change moviePlayer contentURL

In few words, my application is doing that :
1) My main view (RootViewController) has a buton when I tap on it, it displays the player (PlayerViewController) :
2) In my Player, I initialize the video I want to play
-> It's working good, my movie is display
My problem :
When I go back to my main view :
And I tap again on the button, I get a *Program received signal: “EXC_BAD_ACCESS”.*
If I comment self.player.contentURL = [self movieURL]; it's working, but when I let it, iI have this problem.
I read that it's due to null pointer or memory problem but I don't understand why it's working the first time and not the second time. I release my object in dealloc method.
Thanks for your help !
Bruno.
Here is my code :
Root View Controller
RootViewController.h
#import <UIKit/UIKit.h>
#import "PlayerViewController.h"
#interface RootViewController : UIViewController {
IBOutlet UIButton * myButton;
}
#property (nonatomic,retain) IBOutlet UIButton * myButton;
-(IBAction)displayPlayer:(id)sender;
- (void) returnToRoot: (PlayerViewController *) controller;
#end
RootViewController.m
#import "RootViewController.h"
#implementation RootViewController
#synthesize myButton;
-(IBAction)displayPlayer:(id)sender
{
PlayerViewController *playerViewController = [[PlayerViewController alloc] initWithNibName:#"PlayerViewController" bundle:nil];
playerViewController.delegate = self;
playerViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController: playerViewController animated: YES];
[playerViewController release];
}
- (void) returnToRoot: (PlayerViewController *) controller
{
[self dismissModalViewControllerAnimated: YES];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
}
#end
Player View Controller
PlayerViewController.h
#import <UIKit/UIKit.h>
#import <MediaPlayer/MPMoviePlayerController.h>
#protocol PlayerViewControllerDelegate;
#interface PlayerViewController : UIViewController {
UIView *viewForMovie;
MPMoviePlayerController *player;
}
#property (nonatomic, assign) id <PlayerViewControllerDelegate> delegate;
#property (nonatomic, retain) IBOutlet UIView *viewForMovie;
#property (nonatomic, retain) MPMoviePlayerController *player;
- (NSURL *)movieURL;
-(IBAction)goBackToRoot:(id)sender;
#end
#protocol PlayerViewControllerDelegate
- (void) returnToRoot: (PlayerViewController *) controller;
#end
PlayerViewController.m
#import "PlayerViewController.h"
#implementation PlayerViewController
#synthesize player;
#synthesize viewForMovie;
#synthesize delegate;
- (void)dealloc {
[super dealloc];
[player release];
[viewForMovie release];
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"viewDidLoad");
self.player = [[MPMoviePlayerController alloc] init];
[self.player autorelease];
self.player.view.frame = self.viewForMovie.bounds;
self.player.view.autoresizingMask =
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
[self.viewForMovie addSubview:player.view];
self.player.contentURL = [self movieURL];
[self.player play];
}
-(NSURL *)movieURL
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *moviePath =
[bundle
pathForResource:#"myVideo"
ofType:#"mp4"];
if (moviePath) {
return [NSURL fileURLWithPath:moviePath];
} else {
return nil;
}
}
-(IBAction)goBackToRoot:(id)sender{
[self.delegate returnToRoot: self];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
#end
Problem
The second time I call "displayPlayer" I had the EXC_BAD_ACCESS
I solved it !!!
I look on the MPMoviePlayerController to see what kind of variable is contentURL
(NSURL *)contentURL
It means I have also to liberate it.
I do that in my dealloc method putting a nil value:
-(void) dealloc {
[super dealloc];
self.player.contentURL = nil;
[player release];
[viewForMovie release];
}
If I comment self.player.contentURL =
[self movieURL]; it's working, but
when I let it, iI have this problem.
In that case, how is contentURL declared? Does the #property definition include copy or retain?