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
Related
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:
I am making a camera app for iPad. I want the camera app to work only in portrait mode. I had to put in a rotation observation, and force the device to use portrait mode like this:
UIImagePickerController in Landscape
I think this is private API; some of the users on the post suggested that it is.
If so, what other work around can I use to force the overlay to stay in portrait mode only? If I don't add this code it rotates to both portrait and landscape mode.
//Is this private?
#interface UIDevice ()
-(void)setOrientation:(UIDeviceOrientation)orientation;
#end
-(IBAction)InitiateCamera
{
overlayview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 768, 1024)];
...
...
//monitor device rotation
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
//launch camera
[self presentViewController:picpicker animated:YES completion:nil];
}
- (void) didRotate:(NSNotification *)notification
{
//IS THIS PRIVATE?
//Maintain the camera in portrait orientation
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
Use this code instead. I submitted an app and it got approved on itunes
- (void) didRotate:(NSNotification *)notification
{
[[UIDevice currentDevice] performSelector:NSSelectorFromString(#"setOrientation:") withObject:(__bridge id)((void*)UIInterfaceOrientationPortrait)];
}
Yes it is. Though the orientation property appears in the UIDevice header, it's marked as readonly in that header.
UIDeviceOrientationDidChangeNotification is calling multiple times when the device changes orientation. I am unsure why this happens or how to fix it.
What I am trying to do is to keep the contentoffset of the scrollview the same, so when the user rotates the screen the app keeps the page they were on.
The odd thing is when I rotate the screen the first time the code executes like I would want. But every time after that the code executes multiple times and eventually the contentoffset is set o 0.
Here's what I have.
- (void)loadView {
//some code that sizes itself depending on the current orientation
//WILL BE CALLED AFTER EVERY ORIENTATION CHANGE
}
- (void)viewDidLoad {
//begin generating messages
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
//if is portrait and was landscape
if (orientation==1 && temp==2) {
int cal = offsetHolder.x/screenframe.size.height;
offsetHolder.x = cal * screenframe.size.width;
ScrollView.contentOffset = offsetHolder;
}
//if is landscape and was portrait
if (orientation==2 && temp==1) {
int cal = offsetHolder.x/screenframe.size.width;
offsetHolder.x = cal * screenframe.size.height;
ScrollView.contentOffset = offsetHolder;
}
}
On orientation change I change the value of 'int orientation' then call loadview to change the sizing of the view. Then I call viewdidload to get the proper contentoffset
- (void) orientationChanged:(NSNotification *)note {
CGRect screenframe = [[UIScreen mainScreen] bounds];
//holding the current offset
offsetHolder = ScrollView.contentOffset;
if ([[UIDevice currentDevice] orientation] == 1 || [[UIDevice currentDevice] orientation] == 0 || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) {
temp=orientation;
orientation = 1;
[self loadView];
[self viewDidLoad];
}
else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationFaceDown || [[UIDevice currentDevice] orientation] == UIDeviceOrientationFaceUp){
temp=orientation;
}
else{
temp=orientation;
orientation = 2;
[self loadView];
[self viewDidLoad];
}
}
EDIT:
I have found the problem. What I am doing is creating another instance of self.view instead of overwriting this one. Is there an easy way to destroy this view and re-initialize it?
EDIT2:
Have found a fix. I stopped calling loadview and viewdidload as per jsds' instructions. And instead moved all code in my loadview to another function that I called from loadview. All this code does is instantiate the UI (initview) objects and places them in the correct places depending upon orientation.
Then I create another function that removes all subviews from the view. Then on orientation change I call this function and my initview to destroy all subviews and then recreate them on orientation change.
UIDeviceOrientation basically has 6 different states, namely two portrait, two landscape, and face up and face down. So lets say when you pick up your device from flat position to vertical position, the notification will be triggered.
You can filter the faceup, facedown, and unknown states by using the macro UIDeviceOrientationIsValidInterfaceOrientation
UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];
// Ignore changes in device orientation if unknown, face up, or face down.
if (!UIDeviceOrientationIsValidInterfaceOrientation(currentOrientation)) {
return;
}
If you still find the notification getting triggered multiple times, I am afraid you may need to use your custom logic with flags to check the previous and current value.
In my case, since I use reactive cocoa framework, the following code works for me :
if (IS_IPAD) {
#weakify(self);
[[[[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIDeviceOrientationDidChangeNotification object:nil]
takeUntil:[self rac_willDeallocSignal]]
map:^id (NSNotification *notification) {
return #([[UIDevice currentDevice] orientation]);
}]
filter:^BOOL(NSNumber *deviceOrientationNumber) {
UIDeviceOrientation currentOrientation = [deviceOrientationNumber integerValue];
//We ignore the UIDeviceOrientationUnknown, UIDeviceOrientationFaceUp and UIDeviceOrientationFaceDown
return UIDeviceOrientationIsValidInterfaceOrientation(currentOrientation);
}]
distinctUntilChanged]
subscribeNext:^(id x) {
#strongify(self);
//do something here...
}];
}
Here the distinctUntilChanged method makes sure the code gets triggered only when the orientation changes to a new valid value.
You should never call loadView or viewDidLoad yourself. That's up to the framework to manage.
If you are positioning or resizing views based on the view bounds in viewDidLoad, don't. Move that to viewWillLayoutSubviews. That will be called automatically when the device orientation changes.
Alternatively, use autolayout constraints and then you won't have to do anything at all.
I'm writing a program that detects a change in orientation of the device (portrait to landscape, etc.). When the device is in portrait a collectionview should be displayed and a scrollview should be hidden. When the device is in landscape mode the collectionview should be hidden and the scrollview should be displayed.
Through NSLogs I have confirmed that rotating the device is detected. and the hidden property is being set to YES.
I has essentially the same code working with two scrollviews, but due to performance issues I switched to using a collectionview and now it doesn't work. Any advice would be much appreciated. Thank You!
I have this code in the viewDidAppear method:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(detectOrientation) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
And this code in the detectOrientation method
-(void) detectOrientation {
if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) ||
([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)) {
[myCollectionView setHidden:YES];
myPanoramicScrollView.hidden = NO;
NSLog(#"collectionView.hidden = %hhd", myCollectionView.hidden);
} else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait) {
myPanoramicScrollView.hidden = YES;
[myCollectionView setHidden:NO];
NSLog(#"collectionView.hidden = %hhd", myCollectionView.hidden);
}
}
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;
}
}