View Orientation changes - ios

Update: I found why it was loading the same view the whole time. I now fixed that. It was a typo
ControllerForSplitViews.m
- (id)init
{
self = [super initWithNibName:#"ControllerForSplitViews" bundle:nil];
if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation)){
self.view = landscapeView;
}
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
self.view = portraintView;
}
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
return self;
}
This works.
Now the problem. When the view is loaded and running I change the orientation and load a different view from the same nib file, Fixed: but as soon as I do this the other UI elements disappears and only the ui elements of my landscape view is kept and when I rotate the device again it doesn't load my portrait view again? Any suggestions why this might happen?
-(void) orientationChanged:(id)object
{
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
{
self.view = portraintView;
}
if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
self.view = landscapeView;
}
}
New Problem, each time I change the orientation it loads the opposite orientation's view
Thanks

I am adding this here as well for incase someone ever reads this, they might want to check out this post here where a simular scenario was discussed
Two views Multiple UIPickerViews Single outlet

Ok so I found a fix that works, but I have no idea why my original code didn't work what I did was:
Remove:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
Remove:
-(void) orientationChanged:(id)object
{
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
{
self.view = portraintView;
}
if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
{
self.view = landscapeView;
}
}
Change:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight))){
self.view = landscapeView;
}else if(((interfaceOrientation == UIInterfaceOrientationPortrait) ||
(interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown))){
self.view = portraintView;
}
return YES;
}
And now it works perfectly

Related

XCDYouTubeVideoPlayerViewController: Exit fullscreen when rotate to UIDeviceOrientationPortrait

I use XCDYouTubeKit library for my iOS project. I present video from nonFullScreen mode with code:
self.videoPlayer = [[XCDYouTubeVideoPlayerViewController alloc] initWithVideoIdentifier:self.youtubeID];
[self.videoPlayer presentInView:self.videoView];
[self.videoPlayer.moviePlayer play];
When iPhone rotate to landscape mode i set FullScreen video with catching rotate current ViewController:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if (fromInterfaceOrientation == UIDeviceOrientationPortrait) {
[self.videoPlayer.moviePlayer setFullscreen:YES animated:NO];
}
But how i can catch rotation XCDYouTubeVideoPlayerViewController in fullScreen video mode??
Thank
My decision
in this class i add in viewDidLoad observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleDidChangeStatusBarOrientationNotification:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
And execution
- (void)handleDidChangeStatusBarOrientationNotification:(NSNotification *)notification; {
if ([self.videoPlayer.moviePlayer isFullscreen] && [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) {
[self.videoPlayer.moviePlayer setFullscreen:NO animated:YES];
}
}
I think the easiest way to get this information is to subclass XCDYouTubeVideoPlayerViewController and override didRotateFromInterfaceOrientation: and/or viewWillTransitionToSize:withTransitionCoordinator:

segue enable Rotation

Can any one help, the code below works from the portrait view when the app starts, if i rotate to landscape if works great and shows the new view, but when rotate back to portrait, instead of getting the original view, I just get a crash, many thanks
`
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self enableRotation];
}
- (void)didRotate
{
[self setNeedsStatusBarAppearanceUpdate];
if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft ||
[UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
[self performSegueWithIdentifier: #"segueToNumbers"sender: self];
}
else if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait ||
[UIDevice currentDevice].orientation == UIDeviceOrientationPortraitUpsideDown){
[self performSegueWithIdentifier: #"segueToChoose"sender: self];
}
}
- (void)enableRotation
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didRotate)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
`
Do not respond to rotation events. You need to design you UI with AutoLayout to adjust to different screen size. in iOS 8 the orientation is irrelevant, your code should consider size classes instead

Custom CollectionView layout - message was sent to deallocated NSDictionary

I'm having trouble switching between two subclassed CollectionViewFlowLayouts.
I call the following method in my collectionViewController:
header:
#property (nonatomic, strong) PortraitFlowLayout *portraitFlowLayout;
#property (nonatomic, strong) LandscapeFlowLayout *landscapeFlowLayout;
Implementation:
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
if (UIDeviceOrientationIsPortrait(toInterfaceOrientation)) {
self.landscapeFlowLayout = nil;
[self portraitFlowLayout];
NSLog(#"Orientation portrait");
} else {
self.portraitFlowLayout = nil;
[self landscapeFlowLayout];
NSLog(#"Orientation landscape");
}
[self.collectionView.collectionViewLayout invalidateLayout];
}
and in the same collectionViewController:
- (LandscapeFlowLayout *)landscapeFlowLayout
{
if (_landscapeFlowLayout == nil) {
_landscapeFlowLayout = [[LandscapeFlowLayout alloc] init];
self.collectionView.collectionViewLayout = _landscapeFlowLayout;
}
[self.collectionView.collectionViewLayout invalidateLayout];
return _landscapeFlowLayout;
}
- (PortraitFlowLayout *)portraitFlowLayout
{
if (_portraitFlowLayout == nil) {
_portraitFlowLayout = [[PortraitFlowLayout alloc] init];
self.collectionView.collectionViewLayout = _portraitFlowLayout;
}
[self.collectionView.collectionViewLayout invalidateLayout];
return _portraitFlowLayout;
}
I know that both layout are valid, and working, since I'm pushing into this viewController form another viewCont, and I've tried to do it with both the landscape and the portrait layout, which works fine.
The problem arises when I change the orientation. The first orientation change is fine, and the layout change as it's supposed to. But when it's then rotated back (sometimes it will rotate back and forth a few times before crashing), it gives me the following error when I trace it with the Zombie template in Instruments:
How can I trace this error further? Or, fix the problem? Any help is greatly appreciated.
Thanks in advance
EDIT
The problem seems only to arise when rotating to portrait.
Chris
Try to use UIDeviceOrientationDidChangeNotification instead willRotateToInterfaceOrientation.
This lines from the Apple's docs:
To support an alternate landscape interface, you must do the following:
Implement two view controller objects. One to present a portrait-only interface, and the other to present a landscape-only interface.
Register for the UIDeviceOrientationDidChangeNotification notification. In your handler method, present or dismiss the alternate view controller based on the current device orientation.
- (void)awakeFromNib
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
//without selector event may be lost
[self performSelector:#selector(updateFrameWithOrientation) withObject:nil afterDelay:0];
}
-(void) updateFrameWithOrientation{
UIInterfaceOrientation deviceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation))
{
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation))
{
}
[self.collectionView reloadData];
}

UITextfield doesn't show keyboard after dismiss from presentMoviePlayerViewControllerAnimated

I am working with an app which required to open "MPMoviePlayerViewController" when clicked on a video file.
There is a tabbarController into our app which has four Navigation controllers for four tabs.
My app only support portrait orientation, but video should support both landscape & portrait orientations. So, I make Subclass of "MPMoviePlayerViewController".
Code of that class..
#interface MyMovieViewController : MPMoviePlayerViewController
#end
#implementation MyMovieViewController
-(void)viewDidLoad{
[self setWantsFullScreenLayout:NO];
}
-(void)viewWillDisappear:(BOOL)animated{
[self resignFirstResponder];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
-(BOOL)shouldAutorotate{
return YES;
}
#end
In First tab, I show Gallery. There is a code to open video file.
UIGraphicsBeginImageContext(CGSizeMake(1,1));
MPMoviePlayerViewController * vc = [[MyMovieViewController alloc] initWithContentURL:[[[elcAsset asset] valueForProperty:ALAssetPropertyURLs] valueForKey:[[[[elcAsset asset] valueForProperty:ALAssetPropertyURLs] allKeys] objectAtIndex:0]]];
UIGraphicsEndImageContext();
// Remove the movie player view controller from the "playback did finish" notification observers
[[NSNotificationCenter defaultCenter] removeObserver:vc
name:MPMoviePlayerPlaybackDidFinishNotification
object:vc.moviePlayer];
// Register this class as an observer instead
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: #selector(doneButtonClick:)
name: MPMoviePlayerPlaybackDidFinishNotification
object: vc.moviePlayer];
[self presentMoviePlayerViewControllerAnimated:vc];
[vc.moviePlayer prepareToPlay];
[vc.moviePlayer play];
Video is working file. It also support both orientations. but when I switch to another tab, then no textfield show keyboard when clicked on it.
Please help. Thanks is advance.
I have solved the issue.
Actually, MPMoviePlayerViewController support both orientations and my app support only portrait. When i dismiss MPMoviePlayerViewController,then parentview of it think that it is Landscape mode.
So, it display landscape keyboard, which's CGPoint is lower than screen. Thats why I am not able to see keyboard.
I have make write following code into my CustomNavigationController.
- (BOOL)shouldAutorotate
{
return [self.visibleViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.visibleViewController supportedInterfaceOrientations];
}
Now, it is working fine.
YOu need to dismiss Your MoviePlayer..
Use this notification that calls when your video is over
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.theMoviePlayer];
and write method of it.
-(void)myMovieFinishedCallback:(NSNotification*)aNotification
{
[self dismissMoviePlayerViewControllerAnimated];
MPMoviePlayerController* theMovie = [aNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:theMovie];
}
You can try this delegate method,
(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{
[myTextField becomeFirstResponder];
return YES;
}
If this does not work, try to find out what is called after dismissing the view and then insert following code... This will definitely work.
[myTextField becomeFirstResponder];

ipad landscape/ portrait image

I am working on UI issue of ipad app development (about image). I have read some documents on apple development site but i cannot find any information about it.
Is there any file convention for image files to distinguish which image the system should load for Landscape/Portrait. Because I see that for launching image, we can use "MyLaunchImage-Portrait.png" & "MyLaunchImage-Lanscape.png". I have tried to add "-Landscape", "-Portrait", "-Landscape~ipad", "-Portrait~ipad" to other images for general use but it fails.
Is there anyone who has encountered this issue before?
Unfortunately there is not standard convention for this other than the iPad's launch images. However, you can use NSNotificationCenter to listen for orientation change events and respond to them accordingly. Here's an example:
- (void)awakeFromNib
{
//isShowingLandscapeView should be a BOOL declared in your header (.h)
isShowingLandscapeView = NO;
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
!isShowingLandscapeView)
{
[myImageView setImage:[UIImage imageNamed:#"myLandscapeImage"]];
isShowingLandscapeView = YES;
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation) &&
isShowingLandscapeView)
{
[myImageView setImage:[UIImage imageNamed:#"myPortraitImage"]];
isShowingLandscapeView = NO;
}
}

Resources