How to change a new nib when I rotate the device? - iphone

I have a helloController which is a UIViewController, if I rotate the device, I want it change it to load a new nib "helloHorizontal.xib", how can I do? thank you.

You could you something like this, (I dont have xcode handy so this code might not be completely accurate)
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if((interfaceOrientation == UIInterfaceOrientationLandscapeRight) || (interfaceOrientation == UIInterfaceOrientationLandscapeLeft)){
WhatYourNewViewClassISCAlled* newView = [[WhatYourNewViewClassISCAlled alloc] initWithNibName:#"NIBNAME" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:newView animated:YES];
}

This is the correct way, I believe. I'm using it in my apps and it works perfectly
triggers on WILL rotate, not SHOULD rotate (waits until the rotate anim is about to start)
uses the Apple naming convention for landscape/portrait files (Default.png is Default-landscape.png if you want Apple to auto-load a landscape version)
reloads the new NIB
which resets the self.view - this will AUTOMATICALLY update the display
and then it calls viewDidLoad (Apple will NOT call this for you, if you manually reload a NIB)
(NB stackoverflow.com requires this sentence here - there's a bug in the code formatter)
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if( UIInterfaceOrientationIsLandscape(toInterfaceOrientation) )
{
[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:#"%#-landscape", NSStringFromClass([self class])] owner:self options:nil];
[self viewDidLoad];
}
else
{
[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:#"%#", NSStringFromClass([self class])] owner:self options:nil];
[self viewDidLoad];
}
}

Related

Navigation Bar missing in iphone

I am very new to iPhone development, but I have been given an iPhone application to debug and I don't know where to start.
The problem is as follows:
The app has a view which has a navigation bar on top. When I press the home button on the device, the application goes to suspended mode I suppose. When I go back to the app from the list I can see the view but without navigation bar. Why would the navigation bar disappear, and how can I fix it?
Here is the code for the same
-(void)viewWillAppear:(BOOL)animated
{
[self prepareNavBar];
}
-(void)prepareNavBar
{
self.navigationItem.hidesBackButton = NO;
CustomNavBar *the_pNavBar = [[CustomNavBar alloc] init];
[the_pNavBar prepareNavbarWithLeftButtonImage:nil leftButtonAction:nil titleImage: [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"ip4_heading_comments.png"]] rightButtonImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"ip4_submit.png"]] rightAction:#selector(postComment) target:self backgroundImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"ip4_background_grey_150px.png"]] navigationBar:self.navigationController.navigationBar isStandardNavBar:NO];
[the_pNavBar release];
}
please let me know if any other code is required
I fixed the issue by the following code
-(void)didBecomeActive:(NSNotificationCenter *)in_pNotif
{
[self performSelector:#selector(test) withObject:nil afterDelay:0.01];
}
-(void)test
{
self.navigationController.toolbarHidden = YES;
}

How to invoke loadNibNamed without losing UISwipeGestures?

I'm loading a different xib when the user flips to landscape and that's working great, but I've noticed that my swipe events aren't registered.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if ([self currentlyInLandscapeMode:toInterfaceOrientation]) {
[[NSBundle mainBundle] loadNibNamed:#"PhotosLandscape" owner:self options:nil];
}else{
[[NSBundle mainBundle] loadNibNamed:#"PhotosPortrait" owner:self options:nil];
}
}
- (BOOL)currentlyInLandscapeMode:(UIInterfaceOrientation)interfaceOrientation
{
return (UIInterfaceOrientationIsLandscape(interfaceOrientation));
}
How can you switch xib's and keep all the state from my previous view/xib?
UPDATE
turns out my IBOutlets still work but my swipe isn't registered
You can't use a nib file to lay out existing objects. A nib file is stored as an archived object graph, so when you load a nib, either with NSBundle's loadNibNamed: or UIViewController's initWithNibName:, a fresh set of objects gets instantiated.
The only way around this would be to use loadNibNamed to instantiate a new set of objects, and use their frame properties to set the frames for your existing objects, which isn't a great solution.
Turns out I just needed to re-register the swipe event after each nib is loaded (like so)
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if ([self currentlyInLandscapeMode:toInterfaceOrientation]) {
[[NSBundle mainBundle] loadNibNamed:#"VotePhotosLandscape" owner:self options:nil];
}else{
[[NSBundle mainBundle] loadNibNamed:#"VotePhotosViewController" owner:self options:nil];
}
[self wireupSwipeEvents];
}
- (BOOL)currentlyInLandscapeMode:(UIInterfaceOrientation)interfaceOrientation
{
return (UIInterfaceOrientationIsLandscape(interfaceOrientation));
}
- (void)wireupSwipeEvents
{
UISwipeGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[recognizer setDirection:UISwipeGestureRecognizerDirectionLeft];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
}

Change nib programmatically when orientation changes

I load my nibs like this in the init:
self = [super initWithNibName:#"PageView_iPhone" bundle:nil];
But how do I change this during runtime (i.e. after the init) if the orientation changes? initWithNibName won't work.
If you really want to load a different nib, you could use:
[[NSBundle mainBundle] loadNibNamed:#"PageView_iPhone" owner:self options:nil];
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:#"PageView_iPhone"
owner:self
options:nil];
PageView_iPhone* myView = [nibViews objectAtIndex:0];
During init, I setup my views (create them programatically) and create extra CGPoint's for center positions or CGRect's for frames for each view in the view controller.
After the views are created in init, I call method named layoutViewsForOrientation to set the initial position, passing in the current status bar orientation. When the orientation changes, I use this code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
BOOL result = NO;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
result = (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
result = YES;
}
if( result == YES ) [self layoutViewsForOrientation:interfaceOrientation];
return result;
}
There may be an easier way, but this works well for my needs.

Flipping a Video Horizontally in Xcode

I have a video such that when I play it in full view and flip the simulator horizontally the video would not flip. How can I make the video flip according to the iPhone's accelerometer?
Here is the code for the video if it helps:
- (void)viewDidAppear:(BOOL)animated {
NSBundle *bundle=[NSBundle mainBundle];
NSString *moviePath = [bundle pathForResource:#"MainPageMovie" ofType:#"mp4"];
NSURL *movieURL=[[NSURL fileURLWithPath:moviePath] retain];
MPMoviePlayerController *theMovie = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
theMovie.scalingMode = MPMovieScalingModeAspectFill;
theMovie.view.frame = CGRectMake(115.0, 156.0, 200.0, 150.0);
[self.view addSubview:theMovie.view];
[theMovie play];
[super viewDidLoad];
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
}
Your MPMoviePlayerController view is added as a subview to another view controller's view. In that parent view controller, have you overridden shouldAutorotateToInterfaceOrientation method?
If you are just looking for landscape (horizontal) rotation, you can have your code as below:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
In order to rotate specific subviews of the larger view controller view, (which in your situation would be the case with only rotating the video), you'd have to do CGAffineTransforms. This would allow you to resize a view, rotate it, etc. AFAIK, this is probably the best route to go for rotating a single view.
However, you may want to research more into MPMoviePlayerViewController. Take a look at this post, it seems to address your problem.

how to play different audio files with same media player in a separate view- iphone sdk?

I've been trying and researching for countless hours but for some reason I just cant get my head around it and I know its a simple answer. Please Help!
I have a view with different buttons, -(ScrollViewController1)
the different buttons push in one view, -(b1ViewController)
this view contains the media player,
In a nutshell, I cant figure out how to get the media player to play a different audio file depending on which button in the first view was pressed.
I'm trying not to make a different view with a different media player for every button.
Could someone demonstrate it please so that I can understand it? Thanks a million.
Heres the relevant code-
(ps- theres a reason for the tags, I didnt want to get too much into for the sake of asking a clear question and keeping it straight forward.)
#implementation ScrollViewController1
- (IBAction)pressedb1view {
if (thebutton.tag==101) {
[self performSelector:#selector(dismissb1pop:) withObject:nil afterDelay:0.1];
b1view.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:b1view animated:YES];
}
if (thebutton.tag==102) {
[self performSelector:#selector(dismissb1pop:) withObject:nil afterDelay:0.1];
b1view.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:b1view animated:YES];
}
if (thebutton.tag==103) {
[self performSelector:#selector(dismissb1pop:) withObject:nil afterDelay:0.1];
b1view.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:b1view animated:YES];
}
}
etc, etc, etc....
in the next view which contains the mediaplayer I have-
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#interface b1ViewController : UIViewController {
MPMoviePlayerController *moviePlayer;
NSURL *movieURL;
}
in the .m -
-(void)viewWillAppear:(BOOL)animated {
[[self navigationController] setNavigationBarHidden:NO animated:YES];
NSString *urlStr = [[NSBundle mainBundle] pathForResource:#"music1" ofType:#"mp3"];
NSURL *url = [NSURL fileURLWithPath:urlStr];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
[self.view addSubview:moviePlayer.view];
moviePlayer.view.frame = CGRectMake(0, 0, 320, 40);
[moviePlayer play];
}
EDIT:
Im passing text from the first view to a uilabel on the second view using the following in the first view-
[b1view changeSiteText:#"im stuck here"];
in the second view Im doing this in the .h-
- (IBAction) changeSiteText:(NSString *)str;
and in the .m im doing this-
- (IBAction) changeSiteText:(NSString *)str{
lblSiteTxt.text = str;
}
Is there a way to implement a similar method for the mediaplayer,??? maybe doing
something like
NSString *urlStr = [[NSBundle mainBundle] pathForResource:#"%#" ofType:#"mp3", str];
Im stuck!!
Help!
Do you push the view or present it?
Add a method in the player class which when passed various arguments it plays the appropriate track or whatever. Then the different IBActions will invoke this method.