I am workin on an iPhone app and am relatively new to xcode. I am trying to design my application so that no matter what device is used, the main ui will be center. I have a uiview that contains all of my controls (textfields, submit button). I have this uiview centered in interface builder based on the iPhone 5 simulated metrics. When I test this on an iPhone 4 or below, naturally this uiview is not centered but towards the bottom of the screen. Is there a simple way witin interface builder to have this uiview autocenter based on the device? Do I need to add this in programmatically?
Thanks to anyone who can help!
iPhone 3.5inch = http://bit.ly/14r6R6U
iPhone 4inch = http://bit.ly/WOyQcn
You can use the auto resizing option in the interface builder. Fix the top margin and bottom margin and set flexible height
If you are using Xcode 4.5 onward then you can make two different xibs for iPhone 3.5 inches and iPhone 4 inches like:
this will easy to maintain all view components .
Initially create the baseView with the size of (320,480) then add the view as subview of the baseview.
then Do like this,
CGRect _baseFrame=baseView.frame;
_baseFrame.origin=CGPointMake((self.view.frame.size.width-baseView.frame.size.width)/2, (self.view.frame.size.height-baseView.frame.size.height)/2);
baseView.frame=_baseFrame;
If you have auto layout turned on (it is by default), you should center the view both horizontally and vertically, and give it a fixed height and fixed width. Once you have these, you should be able to delete any other constraints. This will keep it centered in any sized screen in portrait and landscape.
You need to explore these things:
The old way - Autosizing masks
The new way - Auto layout
This is enabled by default on new projects. You can turn it off by unchecking a box in the file inspector for the storyboard. Auto layout is ios6 only. Autosizing works on ios6,5,4...
Both of these provide layout engines that do not require code. With both methods you change the settings of objects in the storyboard using the size inspector.
Autolayout is Apple's strongly preferred way forward, but I would recommend trying autoresizing masks first. Autolayout allows you to exert far more control over relative positioning of objects, at the cost of far greater complexity. If you can achieve your result using autosizing, do.
Raywenderlich.com has a good guide to both.
define its in your view controller
#define STATUSBAR_HEIGHT 20
#define SCREEN_HEIGHT (( double )[ [ UIScreen mainScreen ] bounds ].size.height - STATUSBAR_HEIGHT)
#define SCREEN_WIDTH (( double )[ [ UIScreen mainScreen ] bounds ].size.width)
And for example
UIView *view = [[UIView alloc]init];
[view setBackgroundColor:[UIColor purpleColor]];
//for example view height 100 and width 100 then
float xAxis = (SCREEN_WIDTH - 100)/2;
float yAxis = (SCREEN_HEIGHT - 100)/2;
[view setFrame:CGRectMake(xAxis, yAxis, 100, 100)];
[self.view addSubview:view];
And if you making view by xib, then you should use this
Related
I have one storyboard file for iPhone devices, and in one of the views there is a subview that contains a UIPickerView, and, when it runs on the iPhone 4 the UIPickerView is stuck at the bottom of the view as it should be, but when it comes to the iPhone 5, the UIPickerView appears a little above of the bottom of the screen.
If I fix the problem for the iPhone 5, the UIVPickerView won't appear completely when I run it on the iPhone 4. (half of it appears below the screen)
So is there a way to have the UIViewPicker well laid for both iphone 4 and 5 resolutions?
NOTE: I solved the issue by creating a completely new subview with the UIPickerView. Now it is well laid whatever the device is.
When creating the picker, you need to use the size of the screen to determine the location. It seems like you are just putting in the coordinates for the y manually, which only works when using one screen size.
If your view that you are in is the same size as the screen, as it most likely is but may not be, you can do:
int y = self.view.frame.size.height;
and use that as the y-coordinate of your pickerView.
Otherwise, you can find the size of the screen by using:
[[UIScreen mainScreen] applicationFrame].size.width //if in portrait
//or
[[UIScreen mainScreen] applicationFrame].size.height //if in landscape
Then you have to subtract the height of the navigationController from that if you have one.
If you're using autolayout, you should be able to change the constraints the picker uses to get it to stick to the bottom. Select the picker, click the "H"-shaped autolayout menu icon in the bottom right corner of the storyboard, and choose "Bottom Space to Superview". Then delete any constraints attaching the picker to the top of the screen. If that doesn't work, make sure that all of the picker's superviews have constraints to attach them to the bottom, too; you'll have to decide whether you want them to resize or slide down on an iPhone 5.
I fixed the issue. Not sure what was going wrong but I deleted the subview, then created a new one and added the UIPickerView. Surprisingly, now it is well laid whatever the device is.
I'm making an iPhone app, and I'm using storyboard for the majority of the UI. I'm using xCode 4.6 for iOS 6.
Is there a way to make the app work for both iphone4 size and iphone5 sizes?
When I run the app on the iPhone 4 simulator it doesn't look like it's supposed to - the UI elements don't look like they do on the storyboard (which I'm assuming uses the iPhone5 size).
Let me know if you need more info.
You can dynamically access the height of the view and the device, and then make adjustments based on those values. Alternatively, you could use iOS 6's constraints to set a margin between the bottom of the device or between other elements.
To achieve the former, just access the height property of the view:
CGFloat height = [[self view] frame].size.height;
You can also get the height of the device's screen like so:
CGFloat deviceHeight = [[UIScreen mainScreen] bounds].size.height;
deviceHeight -= 20; // remove the tab bar
deviceHeight -= 44; // remove height for a navigation bar?
Now imagine adjust your view's origin based on this value. You can make it hug the bottom of the device, no matter which one you're on.
[aView setFrame:CGRectMake(10, deviceHeight - 10 - 100, 300, 100)];
If you're unable to adjust the layout of the elements, consider using a scroll view as well. Just set the frame using the techniques above, and then set the content size. On smaller devices, you'll be able to scroll to see more content whereas on larger devices, it will all be right there.
In XCode interface builder : I have some images in my view that I need them to be center aligned vertically.
But screen height of Retina 4 and Retina 3.5 differs and I don't like to use OS6 for relative coordinates.
Is there anyway to do this is interface builder or I should write some code?
Using Autolayout in interface builder, select your view, choose the constraints menu in the bottom right of the canvas, and choose center vertically in container. This will apply to both screen sizes.
You should probably use actual code for this.
Luckily, it's fairly straightforward: just obtain the screen height, subtract the image height, and divide by two.
CGFloat height = [[UIScreen mainScreen] bounds].size.height;
CGRect frame = [imageView frame];
frame.origin.y = (height-frame.size.height)/2;
[imageView setFrame:frame];
You can use autoresizing(IB->Size inspector) for it. But you will not see autoresizing options if auto layout is set for xib. You have to remove auto layout(IB->File inspector) first & then set autoresizing properties as you want.
I am using in my app the view size to position a subview in code.
for example like this:
self.view.bounds.size.height
This subview has to be animated in and out of the view.
This has worked perfect on older devices, now I am trying to support iphone 5 and found out that I still get the height of the old devices.
Everything except this animated view adapts perfect for iphone 5.
The only way to get the right size is if I change the size of the view in the xib, downside is
that if I now run my app on iPhone 4 the view size is the 4inch view size.
What is the problem here?
Or is this the way it is supposed to be and I have to create an extra xib file for iPhone 5?
Alright so the answer is the following:
Like #mrwalker said make sure that the view automatically or programmatically resizes.
And be aware of the fact that the view is not yet resized in the viedDidLoad method.
(This was my mistake)
If you need the resized views size do your stuff in viewWillAppear there the view has already the right size.
thanks to #mrwalker and #AndyDev
You need to make sure your view is resized for the device it's running on. You could either:
Create a new Xib for the iPhone 5, as you might for an iPad
Have existing Xib automatically or programatically resize
I would only opt for (1) if you were intending on having a different layout (more / fewer buttons and such).
How you achieve (2) depends on whether you're using iOS 6's Auto Layout or the old autoresize model. Both methods can be controlled in the Utilities > Size Inspector in Xcode, or programatically.
If you have a single view & view controller, allowing the view to automatically resize to the parent window should be enough.
I had a similar issue where I wasn't getting the correct height and using the Autolayout / autoresize didn't achieve the desired effect. I used the following code to determine the screen size and made the changes based on this.
if ([[UIScreen mainScreen] respondsToSelector: #selector(scale)]) {
CGSize result = [[UIScreen mainScreen] bounds].size;
CGFloat scale = [UIScreen mainScreen].scale;
result = CGSizeMake(result.width * scale, result.height * scale);
if(result.height == 1136){
// iPhone 5 (1136px height)
} else {
// Not iPhone 5
}
}
From the iOS Human Interface Guidelines, iOS UI Element Usage Guidelines
On iPhone, take into account the
automatic change in toolbar height
that occurs on device rotation. In
particular, make sure your custom
toolbar icons fit well in the thinner
bar that appears in landscape
orientation. Don’t specify the height
of a toolbar programmatically.
I can see the height changing from 44 points to 32 points in Mail, Twitter for iPhone and Dropbox for example, but when I add a toolbar (with Interface Builder) and have my UIViewController subclass to automatically rotate (shouldAutorotateToInterfaceOrientation: returns YES), the toolbar does not automatically change its height on device rotation.
The UIToolbar Class Reference does not mention this automatic change of height, so am I supposed to change it programmatically even though the HIG says Don’t specify the height of a toolbar programmatically?
Did you check the auto-resizing property of the toolbar?
As noted by yonel and George in the comments from 7KV7 answer, changing the autoresizing mask does not work as intended on iOS 5.
I found another solution by using the -[UIView sizeThatFits:] method. Here is how I did it:
- (void) layoutForInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Adjust the toolbar height depending on the screen orientation
CGSize toolbarSize = [self.toolbar sizeThatFits:self.view.bounds.size];
self.toolbar.frame = (CGRect){CGPointMake(0.f, CGRectGetHeight(self.view.bounds) - toolbarSize.height), toolbarSize};
self.webView.frame = (CGRect){CGPointZero, CGSizeMake(CGRectGetWidth(self.view.bounds), CGRectGetMinY(self.toolbar.frame))};
}
Then I call this layoutForInterfaceOrientation: method in my view controller viewWillAppear: and willAnimateRotationToInterfaceOrientation:duration: methods.
The height is nonetheless changed programmatically but at least the value is not hardcoded.
This behavior is a lot simpler to achieve with auto layout. I've only tested in iOS8 but the following code works for me with the desired animation on orientation change:
public override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
toolbar.invalidateIntrinsicContentSize()
}
If you use a ViewController inside a NavigationController, you can use the NavigationController’s toolbar instead of creating your own, and let it handle the resizing. This is what the ViewController's toolbarItems property is for, actually.