Update interface orientation manually in iOS - objective-c

My iOS application supports all orientations except PortraitUpsideDown.
But in the application I have an view with preferences which I want it to only be shown in Portrait orientation. So whenever this view is shown, it is rotated if needed, to be in portrait mode. That means that user will rotate device in portrait mode also, to setup preferences, and then after closing this view interface should now have portrait orientation.
The problem is, that after preferences view is hidden interface stays in landscape orientation, since I block autorotation after this view is shown.
So after the view is hidden I want to manually update the interface to current device orientation. How can I do it?
self.view.hidden=NO;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.view.alpha=1.0;
[UIView commitAnimations];
This code is called from the OptionsViewController after a LongPressGesture on its superview.

I created a UIViewController extension to force update of orientation of a controller, based on the solution presented by Marek R. Since the new versions of iOS, his solution does not work anymore. I post here my solution to force orientation update (in order to take into account supported orientation methods of controller) without having side visual effects. Hope it helps.
UIViewController *vc = [[UIViewController alloc]init];
[[vc view] setBackgroundColor:[UIColor clearColor]];
[vc setModalPresentationStyle:(UIModalPresentationOverFullScreen)];
[self presentViewController:vc animated:NO completion:^{
dispatch_async(dispatch_get_main_queue(), ^{
[vc dismissViewControllerAnimated:YES completion:completion];
});
}];

All you have to do is add the following to the view controller you're using for your preferences.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

Calling this workaround works for me:
-(void)forceOrientationUpdate {
UIViewController *c = [[UIViewController alloc]init];
[self presentModalViewController:c animated:NO];
[self dismissModalViewControllerAnimated:NO];
[c release];
}

Related

How do I stop a hidden UIView from making UITextFields unclickable?

I have a UITextfield dedicated to dates. When clicked I have a method that shows a UIView with a UIDatePicker as a subview and a method to hide it again. By default this UIView is hidden.
I've noticed that the textfields of my form are no longer clickable. However my UIButtons are still working.
The UIView is a subview of the superview that the UITextFields and UIButtons are also part of. The UIView also takes up the whole area of the window.
The UIView is an outlet also.
Does anyone have any idea what is happening here?
Kind regard
Code:
- (void) hidePickerView {
[UIView animateWithDuration:0.5
animations:^{
[[self datePickerView] setFrame:CGRectMake(0, -250, 320, 50)];
} completion:^(BOOL finished) {
[[self datePickerView] removeFromSuperview];
}];
}
I've also tried putting the following in my viewDidLoad method:
[[self datePickerView] removeFromSuperview];
I was returning NO in my - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField method. Setting this to yes solved the problem.

iOS5,presentModalViewController presenting new view incorrectly

My app mainly supports iOS6+. When considering about iOS5, I added the following judgement.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0) {
self.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:readerViewController animated:YES completion:NULL];
}
else {
self.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentModalViewController:readerViewController animated:YES];
}
However, the modal view presents vertically in my landscape app. I mean, my app is landscape, the modal view just "lies" there, not fullscreen as I set, just cover part of screen while the uncovered is black.
I wonder if anyone could help. Thanks in forward.
Lilac :- What tia said is correct. you dont need to worry about the version.I think you haven't set the Orientation for the ModalView with the required view Oreintation.
Means, if your mainViewController (from which you are presenting ModalView) is supporting only Landscape Mode then in the modalViewController, you have to set the Orientations, restricting to present in Landscape View only.
You should write the Orientation code written in mainViewController also in the modalViewController.
these Methods :-
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
// return YES;
}
-(BOOL)shouldAutorotate{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
Kindly revert if it does not solve your problem and if it does help, you know what to do ;).
First, presentViewController:animated:completion: has been available since iOS 5.0 so you do not have to worry about the version. In case if you really want to check the availability of the method, you should use
if ([self respondToSelector:#selector(presentViewController:animated:completion:)])
For the modal view, you need to set modalTransitionStyle and modalPresentationStyle on presented controller e.g. readerViewController in your case. So your code should be
readerViewController.modalTransitionStyle = UIModalPresentationFullScreen;
readerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentModalViewController:readerViewController animated:YES completion:NULL];

UINavigationBar not hide in iPad but Hides in iPhone

Hello guys I am making a Universal app and the behavior of UINavigationBar on iPad for a ViewController class not working.I googling a lot and also try the many solutions but did't work for me.The setHidden property of UINavigationBar not working on iPad but it working fine in iPhone. UINavigationBar not hide in iPad I use the following way to make it hide but all these way failed in iPad but these working in iPhone:-
[self.navigationController setNavigationBarHidden:YES animated:YES];
and
self.navigationController.navigationBarHidden = YES;
And one more point when I goes from this 1st viewController to another 2nd ViewController and when I pop from 2nd ViewController then it goes to different ViewController class not to 1st ViewController class.
Here's the pastebin link to the ViewController Code:-
First off, are you sure you are suing a UINavigationController, not a UISplitViewController (as Shivan rightfully points out)? Also, are you sure your are running your hide action from your main tread ?
In any case, I found this, that might help you;
if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
CGRect rect = self.navigationController.navigationBar.frame;
rect.origin.y = rect.origin.y < 0 ?
rect.origin.y + rect.size.height
: rect.origin.y - rect.size.height;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.2];
self.navigationController.navigationBar.frame = rect;
[UIView commitAnimations];
}
else
{
[self.navigationController setNavigationBarHidden:shouldHide animated:YES];
}

Transitioning from UIImagePickerController to a second UIViewController

Still feeling pretty green in Objective-C - building my first "real" project and hit an architectural snag early on..
I'd like to present my views and navigation in a fully 'custom' environment - e.g. something where I hide all of the built-in UI controls (e.g. UINavigationController or UITabBar). One specific example (as in the title): moving from a 'main' view directly to a UIImagePickerController, and then right from the UIImagePickerController to a new third view.
Here are the three primary view controllers I'm working with:
MainViewController (custom subclass of UIViewController, contains my main Nav and is in general my primary or 'parent' controller)
ImageEditViewController (custom subclass of UIViewController wherein I overlay some controls on top of a stored image)
UIImagePickerController (built-in Apple class)
There are a couple of approaches I can image for this (but I can't figure out how to do either one):
Use a UINavigationController or UITabBar implementation, but somehow hide the system UI controls and implement my own. I am blocked on this approach because - simply - I don't know how to hide the system UI controls.
Call controller-to-controller or view-to-view transitions manually at specific points in the code. I sort of prefer this method but I can't figure out the best 'approach' to instantiating and managing and transitioning between my controllers. Example of things I don't know: how do I call a second view controller from my main view controller? How do I call a third view controller directly from the second? (Or at least transition to the third directly!)
I assume there is an easy solution here; just something I haven't learned yet about managing views and view controllers outside of Apple's helper classes.
What system UI controls are you talking about? The navigation bar?
You can just do myNavigationController.navigationBarHidden = YES; for a UINavigationCOntroller.
Documentation here.
As for the kind of navigation you should have, that really depends on your use case. Are you trying to achieve a hierarchy or workflow? Then perhaps a navigation controller is what you want. Is each view controller a separate piece that does not necessarily follow a workflow? Then a tab bar controller could work.
For tab bar you should be able to do something like:
myTabBarController.tabBar.hidden = YES;
[[myTabBarController.view.subviews objectAtIndex:0] setFrame:CGRectMake(0, 0, 320, 480)]; // or whatever your screen dimensions are
1.
For hiding navigation bar, it's quite easy:
self.navigationController.navigationBarHidden = YES;
For Hiding TabBar Use this:
- (void) hideTabBar:(UITabBarController *) tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
}
}
[UIView commitAnimations];
}
- (void) showTabBar:(UITabBarController *) tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 431, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 431)];
}
}
[UIView commitAnimations];
}
2.
If you want to easily be able to navigate backwards you should use a navigation controller, it will allow you to pop the view controller when you are done with it. Or you can do something like this (outside of navigation controller):
CustomViewController *controller = [[CustomViewController alloc] init];
[self presentModalViewController:controller animated:YES];

- (void)viewWillAppear:(BOOL)animated detect custom animation

I have a button which when pressed pushes a view controller however i'm using a custom animation so pushViewController: childController animated: is set to NO. What i want to do though is detect this custom animation in my - (void)viewWillAppear:(BOOL)animatedmethod and write an if statement like this;
- (void)viewWillAppear:(BOOL)animated {
if (customAnimation occured) {//Do this}
else {//Do this}
}
This is the method for my button which pushes the view controller.
- (void)nextPressed:(id)sender {
childController = [[CategoryOneDetailController alloc] initWithNibName:xibDownName bundle:nil];
[UIView beginAnimations: #"Showinfo"context: nil];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController: childController animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
[childController release];
}
Any help would be much appreciated, thanks, Sami.
If you don't use standard animations, I think your best bet is to add a property to your pushed view controller that is set to YES in case of a custom animation (and NO by default to not break any existing behavior). Then you can check that property in viewDidAppear:.
If you need your custom logic to be executed after the animation has run, you might want to set up an animation completion handler or block.