I am fairly new to iOS development and just inherited bunch of iOS code.
I am trying to start using auto layout and constraints to make it easier to support different screens sizes and iOS versions. I find that once I change storyboard to use an auto layout, background image no longer change when I rotate the iPad into landscape view. I am not sure if this is auto layout preventing this change or is there some other way to switch the background image. I'd appreciate your help.
Here is my rotate method.
- (void)didRotate
{
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
if ([[UIDevice currentDevice] userInterfaceIdiom] != UIUserInterfaceIdiomPhone)
{
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight)
{
[backgrndView setBackgroundImage:[UIImage imageNamed:#"menu_ipad2.png"] forState:UIControlStateNormal] ;
}
else if (orientation == UIDeviceOrientationPortraitUpsideDown|| orientation == UIDeviceOrientationPortrait)
{
[backgrndView setBackgroundImage:[UIImage imageNamed:#"menu_ipad.png"] forState:UIControlStateNormal] ;
}
[backgrndView sizeToFit];
}
}
Adding new left, right and top constraints of value zero to the underlying view (which was a button) fixed the problem.
I believe the method you're looking to override is didRotateFromInterfaceOrientation: not didRotate
Related
when I create a new Imagese in Xcode I see the following screen
Now I want to specify a separate image for iPad Landscape and iPad Portrait, but there is no such option available.
Offcourse I could do something like
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if((self.interfaceOrientation == UIDeviceOrientationLandscapeLeft) || (self.interfaceOrientation == UIDeviceOrientationLandscapeRight)){
myImageView.image = [UIImage imageNamed:#"image-landscape.png"];
} else if((self.interfaceOrientation == UIDeviceOrientationPortrait) || (self.interfaceOrientation == UIDeviceOrientationPortraitUpsideDown)){
myImageView.image = [UIImage imageNamed:#"image-portrait.png"];
} }
But I want to know if there exist any solution inside the interface builder or not?
No there isn't. Since the Xcode 6 version you can use size classes from image assets to specify a particular resource.
Unfortunately, iPad uses the same size classes (Regular-Regular) for both orientations.
You can only do that programmatically by asking the status bar orientation and load the asset that you need.
I have 2 buttons in a view and following is the screen for RTL works fine:
And in RTL it flips both and shows like this :
I am unable to stop flipping by unchecking respect language direction
I have added Constraint like this :
Its working fine on iOS 8 I want to stop them automatic flipping for iOS 9, Any guidance ?
Set the semantic content attribute of the superview to Force Left-To-Right.
or You can use this in appDelegate,
-(BOOL) isGreaterIOSVersion:(NSString*) version
{
NSString *systemVersion = [[UIDevice currentDevice] systemVersion];
if ([systemVersion compare:version options:NSNumericSearch] != NSOrderedAscending) {
return YES;
}
return NO;
}
add below code to in didFinishLaunchingWithOptions function
if([self isGreaterIOSVersion:9.0]) {
[[UIView appearance] setSemanticContentAttribute:UISemanticContentAttributeForceLeftToRight];
}
it will remove RTL
In my app i trying create a Interface builder supports both Landscape and portrait in ipad and iPhone.
[In Android we used fill parent to autoresize dynamically created UI-Elements.is there any syntax in iOS to autoresizing]
How to UI-elements create dynamically supports both Landscape mode and portrait mode?
How create the view controller to support the Landscape mode and portrait mode?
Is there required to create a all views and UI-elements dynamically?
1)If you will make xib or nib than develop xib or nib in only one mode as portrait or landscape. Than use Autoresizing option as below Image for any control.
http://www.raywenderlich.com/50319/beginning-auto-layout-tutorial-in-ios-7-part-2. You can use this link for auto layout.
But Auto layout is not work properly as you want. so u need to set frames of control pro grammatically evenif u r using autolayout.
2) And If you want to develop dynamically than using below code you can set frame of all controls.
In ViewwillAppear.
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(orientationChanged) name:UIDeviceOrientationDidChangeNotification object:nil];
in viewdidload
set your controls as below.
UILabel lbl - [UILabel alloc]init];
-(void)orientationChanged{
if(Orientation is portrait){
[lbl setFrame:for portrait];
}else{
[lbl setFrame: for landscape];
}
If device change mode than above notification fire and in that method. you can set frame of control.
I hope you will get your answer.
You can use auto - layout for providing both the portrait and landscape mode.
For more details, check this : What is Auto Layout?.
You have to set the constraints for landscape and portrait mode to work. Like if you want a button at the top, you can set constraints on it : from top and left and so on.
If you want a UI element to work change dynamically, you just need to change frame on orientation as per your requirement. Sample code is here :
# pragma mark - Orientation related methods
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration NS_AVAILABLE_IOS(3_0)
{
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
[self deviceRotatedToLandscapeMode];
}
else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[self deviceRotatedToLandscapeMode];
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
[self deviceRotatedToPortraitMode];
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
[self deviceRotatedToPortraitMode];
}
}
- (void) deviceRotatedToPortraitMode {
self.mTableView.frame = CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height);
}
- (void) deviceRotatedToLandscapeMode {
self.mTableView.frame = CGRectMake(0.0, 0.0, self.view.frame.size.height, self.view.frame.size.height);
}
The most reliable approach -
Create a method in your view controller -
-(void)setFrameForOrientationChange:(UIDeviceOrientation*) o {
//...
implement your code for frame settings..
}
Now i realized when i writing my app for only iPad version.
My iPad iOS Version is iOS 5.1.
Yes, i need to check the iPad Orientation before load my Data.
So i check with following codes.
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
{
self.originalLandScape = CGRectMake(0, 48, 1024, 704);
self.originalPortrait = CGRectMake(0, 48, 768, 960);
self.txtView.frame = self.originalLandScape;
}
else
{
self.originalPortrait = CGRectMake(0, 48, 768, 960);
self.originalLandScape = CGRectMake(0, 48, 1024, 704);
self.txtView.frame = self.originalPortrait;
}
Because i need to set the fix size to my UITextView.
However i realized that when my iPad is with Landscape and put down to floor horizontally , It's not correct to set UITextView size.
But when i get my iPad from floor and holding in my hand with Landscape like reading book , my above codes is work.
Is there any different between those two?
I don't know how to solve it.
Thanks you for any suggestions and helps.
You are correct - iPad orientation is not only four, it is six:
UIDeviceOrientationLandscapeLeft
UIDeviceOrientationLandscapeRight
UIDeviceOrientationPortrait
UIDeviceOrientationPortraitUpsideDown
UIDeviceOrientationFaceUp
UIDeviceOrientationFaceDown
Your else clause therefore applies not just to the Portrait orientations, but to FaceUp and FaceDown as well.
I suspect that what you actually want to use is the Interface orientation. This may or may not be the same orientation as the Device orientation (depending on your app's supported orientations) - but if you want to draw a UI element correctly for a particular orientation, it will be the orientation of the rest of the interface that matters, not the device orientation.
There are only four interface orientations:
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
You can get these with the UIViewController property interfaceOrientation and check them with the UIKit functions UIInterfaceOrientationIsLandscape() and UIInterfaceOrientationIsPortrait()
Try this in your code
if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation))) {
...
} else {
...
}
I have an iPad app that I would like to work in the sideways orientation instead of just portrait. I have programatically placed images, labels, and buttons into my view and used CGRectMake (x,x,x,x) to tell them where to go on the view into the center. When the app rotates horizontally, I need my labels and buttons to shift up (since they can't go down as far when in landscape mode), but stay in the center. Here is some code I've been playing with:
if((self.interfaceOrientation == UIDeviceOrientationLandscapeLeft) || (self.interfaceOrientation == UIDeviceOrientationLandscapeRight))
{
lblDate = [[UILabel alloc] initWithFrame:CGRectMake(384-(fieldWidth/2)-30,controlTop+45,120,40)]; //these dimensions aren't correct, though they don't matter here
lblDate.text = #"Date:";
lblDate.backgroundColor = [UIColor clearColor];
[contentView addSubview:lblDate];
} else {
//the orientation must be portrait or portrait upside down, so put duplicate the above code and change the pixel dimensions
}
Thanks for your help!
Take a look at this: iphone/ipad orientation handling
You just specify each control location depending on the rotation.
I know this might be a bit of an old question now looking to the date, but I just very recently faced the same problem. You could stumble upon many suggestions such as transforming main view's subviews or it's layers. Non of this worked for me.
Actually the solitary solution I've found is that since you want your UI controls to be located dynamically then don't deploy them mainly in the interface builder. The interface builder can be helpful knowing the desired locations for dynamic controls in both portrait and landscape orientations. i.e make two separate test views in the interface builder, one portrait and the other landscape, align your controls as you wish and right down X, Y, Width and Height data just to use with CGRectMake for each control.
As soon as you write down all needed positioning data from the interface builder get rid of those already drawn controls and outlets/actions links. They will be of no need now.
Of course don't forget to implement UIViewController's willRotateToInterfaceOrientation to set control's frame with each orientation change.
#interface
//Declare your UI control as a property of class.
#property (strong, nonatomic) UITableView *myTable;
#end
#implementation
// Synthesise it
#synthesize myTable
- (void)viewDidLoad
{
[super viewDidLoad];
// Check to init for current orientation, don't use [UIDevice currentDevice].orientation
if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft || self.interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
myTable = [[UITableView alloc] initWithFrame:CGRectMake(20, 20, 228, 312)];
}
else if (self.interfaceOrientation == UIInterfaceOrientationPortrait)
{
myTable = [[UITableView alloc] initWithFrame:CGRectMake(78, 801, 307, 183)];
}
}
myTable.delegate = self;
myTable.dataSource = self;
[self.view addSubview:myTable];
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight || toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
// Show landscape
myTable.frame = CGRectMake(20, 20, 228, 312);
}
else
{
// Show portrait
myTable.frame = CGRectMake(78, 801, 307, 183);
}
}