Best implementation for transitionWithView in Navigation Controller when the user tap BACK - ios6

I have 2 UIViewControllers inside a NavigationController.
The first one, A, has just an UISearchBar on top of a tableView, as the tableHeader.
The second one, B, has a view in the upper part of the screen (let's call it a custom TableHeader) and a table below this view.
I wanted to simulate the modal transitionFlipFromRight when pushing from UIViewController A to UIViewControllerB and to simulate the modal transitionFlipFromLeft when popping from UIViewController B to UIViewController A when the user tap the navigationItem.backBarButtonItem.
No problem for the push side:
UIViewController *vcB = [UIViewController alloc] init];
[self.navigationController pushViewController: vcB animated: NO];
[UIView transitionWithView:self.navigationController.view
duration:0.8
options:UIViewAnimationOptionTransitionFlipFromRight
animations:nil
completion:nil];
It works as expected.
I have problems implementing the pop, the switch back from UIViewController B to UIViewController A.
I added this code in the UIViewController B:
-(void) viewWillDisappear: (BOOL) animated
{
[super viewWilDisappear: NO]
[UIView transitionWithView:self.navigationController.view
duration:0.8
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:nil
completion:nil];
}
I can see the flip but I am not satisfied with the result because for a fraction of a second after the switch from B to A I can still see the B custom tableHeader, moved from left border by 10 points.
Should I manage the transition from B to A in viewWillDisappear or I am totally wrong in doing this?
If I am wrong, What is the correct way to handle the pop animation?
Thanks
Nicola

Why dont you try this in your viewWillDisappear itself and check whether this works?
UIViewController *vcA = [UIViewController alloc] init];
[[self retain] autorelease];
[self.navigationController pushViewController: vcA animated: NO];
[UIView transitionWithView:self.navigationController.view
duration:0.8
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:nil
completion:nil];
[self.navigationController popViewControllerAnimated:NO];
This is a tested code. So it works fine. This should help you.

Related

Can't dismiss AVPlayerViewController in iOS16

Since iOS 16 made changes to AVPlayerViewController, the dismiss button ('x') in the top left corner simply doesn't work. The 'tap' is normal, but it feels like the UIButton target doesn't do anything. I feel like I'm missing something obvious. Is there a delegate method or setting that needs to be used for it to work? It all worked perfectly before iOS 16. Implementation below:
AVPlayerViewController *vc = [[AVPlayerViewController alloc] init];
vc.player = [AVPlayer playerWithURL:[NSURL URLWithString:videoInfo.VideoURL]];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:vc animated:NO completion:nil];
Using animation. It can be fixed but I don't know why.
[self presentViewController:vc animated:YES completion:nil];

UINavigationController pushes UIViewController and nothing happens

Here are the relevant lines of code:
...
if([top class] == [SitesViewController class]){
BackupsViewController *backup = [[BackupsViewController alloc] initWithStyle:UITableViewStyleGrouped andID:cg_id];
[websites pushViewController:backup animated:NO];
[websites pushViewController:details_controller animated:YES];
websites is a navigation controller, and it is not nil.
Now the first time I run it, it works fine. But if I sign out, and sign back in it doesn't work. In fact, nothing happens. It stays on the same page it is on. I have already checked to make sure nothing is nil. I also know that I am entering into this if statement and none others.
Here is the logout function:
AppDelegate * appDelegate = (GCAppDelegate*)[[UIApplication sharedApplication] delegate];
[appDelegate.tabBarController setSelectedIndex:0]
UINavigationController * topViewController = appDelegate.tabBarController.viewControllers[0];
[topViewController presentViewController:loginScreen animated:YES completion:nil];
[topViewController popToRootViewControllerAnimated:TRUE];
[self deteleKeysAndTokens: (NSString*)k_apiSecret withAccessToken: (NSString*)k_accessToken withAccessSecret:(NSString*) k_accessSecret withkAPIKey: (NSString*)k_apiKey];
In case it might help, the backupViewController is downloading a list of websites, and the detailsViewcontroller is getting information about the websites. In fact, after making the call:
[websites pushViewController:backup animated:NO];
[websites pushViewController:details_controller
animated:YES];
(This is from the first bit of code I posted.)
I check to see what the topViewController is:
UIViewController * topView = websites.topViewController;
The topViewController is the details_controller. So I know it is being pushed onto the stack. However, nothing is happening. I am on the same view I started on. I was thinking that maybe it was because I hadn't gotten all the data. But that doesn't explain (a) why it works the first time through and (b) why it just doesn't display a blank page.
It's hard to say what is wrong as from code it's not clear what is the hierarchy of views.
First make sure you are using the correct navigation controller:
UINavigationController * websites = viewController.navigationController;
[websites pushViewController:anotherViewController animated:NO];
Also I'm not sure why your logout function is so complicated. Where do you execute it?
Anyway, its not good to present view controller on navigation controller and then pop it to root. And also both of them are animated...
Please provide more code.

completion:nil on presentModalViewController

When I set
[self presentModalViewController:Facebookcontroller animated:YES];
to
[self presentViewController:Facebookcontroller animated:YES completion:nil];
to erase the presentModalViewController:animated is deprecated: first deprecated in iOS 6.0
pops another warning:
Instance method '-presentModalViewController:animated:completion:' not found (return type defaults yo 'id')
Are you sure self is a UIViewController in this context. You can call this code only from another UIViewController.
Make sure you initialize the Facebookcontroller class first, you cannot pass just the class. Facebookcontroller *facebookController = Facebookcontroller alloc] init];
For iOS 6 use:
[self presentViewController:Facebookcontroller animated:YES completion:^{
//Do whatever you want to do when the controller 'Facebookcontroller' is presented.
}];
or
[self presentViewController:Facebookcontroller animated:YES completion:nil];
You can find the reference here.

Why does the MPMoviePlayerController call MPMoviePlayerPlaybackDidFinishNotification, when enter in fullsceen mode

I want to display a MPMoviePlayerViewController in full screen mode, but when the fullscreen button of the movieplayercontroller view is beeing pressed, first the MPMoviePlayerWillEnterFullscreenNotification gets called, as expacted, but than the MPMoviePlayerPlaybackDidFinishNotification is also beeing sent. As a reason it says MPMovieFinishReasonPlaybackEnded and i don't know, what i'm doing wrong. (In addition, i use iOS 6.0 and XCode 4.5.1)
My expactations are, that only the MPMoviePlayerWillEnterFullscreenNotification is beeing called.
Short explanation to the code below:
The MovieplayerViewController's view is beeing displayed in a tiny subview in my content view. When tapping the fullscreen-button, it first gets displayed as fullscreen but than also calls the exit button and stops playing (no crashes, nothing else).
MPMoviePlayerViewController *playerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
[playerViewController.moviePlayer setControlStyle:MPMovieControlStyleEmbedded];
[playerViewController.moviePlayer setScalingMode:MPMovieScalingModeFill];
CGRect rect = videoView.frame;
rect.origin = CGPointZero;
[playerViewController.view setFrame:rect];
[playerViewController.moviePlayer prepareToPlay];
//movie this is my contents subview, where i add the viewcontroller's view as a subbview
[self.videoView addSubview:playerViewController.view];
[self.videoView setHidden:NO];
playerViewController.moviePlayer.useApplicationAudioSession = NO;
[playerViewController.moviePlayer play];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerDidFinishNotification:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:playerViewController.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerWillEnterFullscreenNotification:)
name:MPMoviePlayerWillEnterFullscreenNotification
object:playerViewController.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerWillExitFullscreenNotification:)
name:MPMoviePlayerWillExitFullscreenNotification
object:playerViewController.moviePlayer];
//i store the movieplayer in a property, so i can use it for further operations
self.myPlayer = playerViewController;
[playerViewController release];
And thats it!
When the resize (or fullscreen) button is being pressed, the moviePlayerDidFinishNotification: method also is being called
- (void)moviePlayerDidFinishNotification:(NSNotification*) aNotification {
int reason = [[[aNotification userInfo] valueForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
if (reason == MPMovieFinishReasonPlaybackEnded) {
//movie finished playin
//in debug mode, it stops right at the NSLog
NSLog(#"");
}
else if (reason == MPMovieFinishReasonUserExited) {
//user hit the done button
}
else if (reason == MPMovieFinishReasonPlaybackError) {
//error
}
.. }
Is there something i do wrong or is there probably a change since iOS 6.0?
Ok, seems to be that there are some problems in the MPMoviePlayerViewController. What helped is to simply us the MPMoviePlayerController only.
For future reference the reason that your player showed in a small window was because you were setting:
[playerViewController.moviePlayer setControlStyle:MPMovieControlStyleEmbedded];
[playerViewController.moviePlayer setScalingMode:MPMovieScalingModeFill];
CGRect rect = videoView.frame;
rect.origin = CGPointZero;
[playerViewController.view setFrame:rect];
[playerViewController.moviePlayer prepareToPlay];
//movie this is my contents subview, where i add the viewcontroller's view as a subbview
[self.videoView addSubview:playerViewController.view];
[self.videoView setHidden:NO];
When you use an MPMoviePlayerViewController it creates it's own view controller. These calls are not necessary and will only create bizarre behavior. That's why the MPMoviePlayerController worked properly because it's designed to work inside another view controller.

How to set the starting orientation to landscape?

Hi I was checking the orientations changes of iOS6 and I made everything work fine except one thing. There is no way to start the app on landscape.
How can I do to start the app on landscape? I found this How to force a UIViewController to Portrait orientation in iOS 6 but that's not working, the app ALWAYS start in portrait and I needed to start it on landscape...
When I go to an other view and then go back to the "initial view" it is on landscape! But when the app starts it's on portrait...
Thank you!!
----------------------------- UPDATE -------------------------------
This is how I'm loading from the app delegate the main view:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
myViewController = [[myViewController alloc] init];
self.navController = [[UINavigationController alloc] initWithRootViewController:myViewController] ;
[self.window setRootViewController:navController];
[self.window makeKeyAndVisible];
----------------------------- UPDATE 2------------------------------
I made it work, I changed the previous code for:
self.navController = [[UINavigationController alloc] init] ;
[self.window setRootViewController:navController];
[self.window makeKeyAndVisible];
[navController presentViewController:myViewController animated:NO completion:NULL];
I hope this is useful for someone else!
Have you tried this?
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:YES];
or
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
This is working for me in both iOS 6 and iOS 5
I have another problem on trying to rotate the screen than I realize I was making the mistake of try to load the new screen with:
[self.navigationController presentModalViewController:controller animated:YES];
instead of:
[self.navigationController pushViewController:controller animated:YES];
the second one works but the first one wasn't doing what I expected.
This is how I made it work:
self.navController = [[UINavigationController alloc] init] ;
[self.window setRootViewController:navController];
[self.window makeKeyAndVisible];
[navController presentViewController:myViewController animated:NO completion:NULL];
I hope it helps someone else!
I've been wrestling with this too - this is how I've fixed it:
In viewDidLoad:
CGRect frame = self.view.bounds;
if (frame.size.height > frame.size.width) {
//hack to force landscape
CGFloat holdHeight = frame.size.height;
frame.size.height = frame.size.width;
frame.size.width = holdHeight;
self.view.bounds = frame;
}
But I'd prefer a better way.

Resources