Using Xcode 8 Interface Builder, is it possible to position elements differently for one specific device (iPhone 4s)? Only this device is too small for regular design, so product requirement is to re-arrange the buttons for iPhone 4s only.
I tried varying for trait, but it affects many devices simultaneously.
So far, I was only able to workaround this with code:
if UIScreen.mainScreen().bounds.height <= 480 {
// iPhone 4s
} else {
// other
}
After investigation, no, it seems impossible to work on one specific device with Xcode 8.0 Interface Builder. Trait variations will only let you work with regular/compact height/width, so that's a max of four distinct groups of devices:
rH rW
rH cW
cH rW
cH cW
Related
I completed the development of my app, using a layout of form components that perfectly suited the iphone 6 in the simulator. I used a combination of Theme styles (always Base Resource) and some coded tweaks to the look and feel.
When i ran this up against the iphone 5 i had expected naively the display to shrink to fit, as you may expect with browser applications, but instead my components (labels largely) went off the edge of their containers. Panic.
I ended up having to measure the display height and judge the device from there and code up different sized components to get the right fit. This took some time.
Next to TestFlight in the AppStore. As part of wider testing I decided to install on my iPad 3, only to find the layout components rendered all very small. Panic.
I have now spent a couple of days resolving this just about. I basically use this method to determine the type of device 'category' to then apply the size of font or fontimage etc.
public static ScreenSizeEnum getScreenSize() {
if (Display.getInstance().isTablet() && Display.getInstance().getDisplayHeight() > 2000) {
return ScreenSizeEnum.TABLET;
}
else if (Display.getInstance().getDisplayHeight() < 950) {
return ScreenSizeEnum.SMALL;
} else if (Display.getInstance().getDisplayHeight() > 949 && Display.getInstance().getDisplayHeight() < 1200) {
return ScreenSizeEnum.MEDIUM;
} else {
return ScreenSizeEnum.LARGE;
}
}
This is unsurprisingly not foolproof. The Ipad 6 plus is not recognised as a tablet but has a large display height, but one of the Nexus's are a tablet but has a small display height.
My question is, how on earth do you get around this problem?
Tablets and phones come in different sizes but its important that you still get a quality component render regardless of form factor.
The CN1 KitchenSink demo didn't really address it. Many thanks in advance.
From the description of the issue it seems you are thinking about a tablet as a "large phone" which is the wrong way to look at it. A tablet has similar density to a phone but more real-estate in inches which means you need to design your app so it will use up the additional space more effectively.
Here are two screenshots of the same Kitchen Sink demo one running in an iPad and the other running in an iPhone. Notice the UI's look very differently as we adapted the UI to use up the additional space. Image's (e.g. multi-images) and fonts are determined by density not by the amount of pixels as the goal is to use the extra space not to fill up the screen with larger images/text.
I am working on a project using Xamarin.iOS and I have a situation where a behavior in the simulator inexplicably is not the same on an actual device (setting the region of a mapview centers differently).
I want to be able to set a value for a variable at runtime based on whether the app is running on the simulator or a real device. How can I detect this?
You can execute different code at runtime like this:
if (ObjCRuntime.Runtime.Arch == Arch.DEVICE) {
} else {
}
But it's always good to investigate (ask around here, forums, bug reports) why the behaviour differs between the two (just to make sure it does not hide a bug that could bite you later).
When I first started programming for iOS (with Cocos2d) I used a bunch of hardcoded coordinates based on 320x480 screen size for the iPhone. I just realized that I need to include at least a basic version of iPad and the iPad mini.
I have read these:
cocos2d (but i'm not sure if this is the best way?)
cocos2d:Convert iPhone App to Universal App
converting coordinates:
Convert coordinates from iPhone screen size to iPad screen size
converting iphone to ipad:
http://iphonedevelopment.blogspot.com/2010/04/converting-iphone-apps-to-universal.html
Apple's documentation on creating universal app:
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/AdvancedAppTricks/AdvancedAppTricks.html#//apple_ref/doc/uid/TP40007072-CH7-SW24
is there an easy way to convert the graphical display from iPhone to iPad without editing every part of my code where I used a hard coded value? (50 spots, all in 1 file)
what's the best practice for future coding with iOS/Cocos2D coordinates? should I do
#define SPACE_SHIP_X_IPAD 384
#define SPACE_SHIP_X_IPHONE 160
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
`[ship.setPosition ccp:(SPACE_SHIP_X_IPHONE,0)];`
} else {
`[ship.setPosition ccp:(SPACE_SHIP_X_IPAD,0)];`
}
(by the way, will someone who knows how to format this code with the "#" sign, plz teach me how to format the above code?)
is it recommended that I create 2 different apps - one for iphone and one for iPad? or this universal approach of only 1 app, and then selecting the distribution type when I submit to Appstore?
are Mac versions of apps the same distribution channel as the app store for iPhone and iPad? what are the advantages or disadvantages to distributing on Mac as well? (i'm guessing it's not good because graphics would have to accomodate something liek the massive iMac?)
just to make sure - my app file (which doesn't use anything iphone specific like calling) will work on the iPod and iPad Mini without ANY extra work, right?
Any help would be greatly appreciated. I will upvote all good attempts
It looks like your approach is overly complicated. Making a universal application typically involves never hard-coding position values, but rather calculating these position values based on the bounds of the device.
For example:
//Button in center for universal
CGPoint buttonOffset = CGPointMake( ([[UIScreen mainScreen] bounds].size.width - button.frame.size.width) / 2, ([[UIScreen mainScreen] bounds].size.height - button.frame.size.height) / 2);
button.frame = CGRectMake(buttonOffset.x, buttonOffset.y, button.frame.size.width, button.frame.size.height);
Use similar concepts to create buttons (or ships) with positions that are relative to the screen bounds. This will save you a lot of time and grief.
One thing to note is that the "bounds" of the screen will not factor in the device orientation. If you want to support multiple orientations you will find it useful to create a utility method to handle that logic for you.
Something like:
+ (CGSize) deviceSize {
CGSize size;
if(UIDeviceOrientationIsLandscape([[UIDevice currentDevice] orientation])){
size = CGSizeMake([[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width);
} else {
size = CGSizeMake([[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
}
return size;
}
I know you want an easy solution so you don't have to change all your values but I would recommend biting the bullet and changing the values. It will help you a lot in the long-run. Not only for this application but the practice will help in any application you create in the future.
Is it recommended that you create two different apps for universal? No, it is not recommended. You can select "universal" when creating the xcode project and also change it in an existing project. You will not need to create two builds or binaries either. Apple will recognize it as universal and make it available in the store for all devices. However, you will need to create multiple versions of a splash screen to accommodate different screen sizes and pixel densities.
are Mac versions of apps the same distribution channel as the app store for iPhone and iPad? Sort of... you can deploy to the app store and you gain more freedom since you can package and distribute the OSX binary yourself -- but you will have to create a separate app since you will most likely be using CocoaTouch libraries which are not supported on the mac. You will want to preserve functionality that does not use CocoaTouch such as your Rendering and Game Logic. If you are deploying to OSX, the large screen sizes will be the least of your concern. Advantages: Wider Audience. Disadvantages: Requires a lot of planning when architecting your app/game so you can reuse as much code as possible and cater to all screens.
just to make sure - my app file (which doesn't use anything iphone specific like calling) will work on the iPod and iPad Mini without ANY extra work, right? Well... some extra work With some additional image assets for home screen icons and a splash screen you will be good to go.
I do this with data files shared through iCloud so that data appears in the right place on both devices... X *= 768 / 320 and Y *= 1024 / 480. To go back to iPhone from iPad resolution, just divide instead of multiply. It's simple and precise. Then if you need to, record which set of coordinates your data is configured for.
The new iPhone is being presented..
it has a new resolution aspect ratio. (1136 x 640)
Does anyone know how to upgrade apps to support the new resolution??
Thanks!
Normal UI components like buttons etc. should be update with the new SDK - Like on the MBP Retnia. But graphics you have made like images, needs to be update with a bigger dpi - This is only a guess, but that was how it work to MBP Retnia
We are using Canappi to generate the Objective-C code that works on both resolutions (and with iPad too). Canappi works like Interface Builder, but in a textual form (which is much easier to use if you ask me). This is how you specify the position of your controls for each resolution and/or form factor:
layout myTabletLayout {
text name (10,60,100,30) { ... }
}
layout myPhoneLayout {
text name (10,60,100,30 + 0,10,0,2) { ... }
tablet myTabletLayout ;
}
the +0,10,0,2 is a shift that is applied to the original coordinates when the app runs on an iPhone 5. That means that you can easily resize tables, space out controls or even, and that's really cool, bring controls which are displayed off screen on the iPhone 4, back into the iPhone 5 view bounds.
I have an iPad app that I would like to make Universal, however this seems alarmingly difficult. I've changed things around so that I support both builds, but when building, I get lots of errors about using UIPopOvers. Here're my questions:
Why does UI_USER_INTERFACE_IDIOM() not compile or register on 3.1.3?
Can I conditionally have variables in a class definition based on UI_USER_INTERFACE_IDIOM()?
If not, should I make two different view controllers?
Thanks!
Why does UI_USER_INTERFACE_IDIOM() not
compile or register on 3.1.3?
The UI_USER_INTERFACE_IDIOM macro is only available starting with 3.2. Same restrictions for the userInterfaceIdiom property of UIDevice. This means that you can only get universal application starting with SDK 3.2.
Can I conditionally have variables in
a class definition based on
UI_USER_INTERFACE_IDIOM()?
No. The UI_USER_INTERFACE_IDIOM macro is only a runtime shortcut to get the current UI idiom of the device.
If not, should I make two different
view controllers?
If you have very different UI between the two devices, it is wiser to use two different view controllers, and to create the right one at runtime (in the application controller for example) by using the UI_USER_INTERFACE_IDIOM macro.
I had pretty good luck with just selecting the target then going to Project->Upgrade current target for iPad.
My app is pretty simple, consisting mostly of table views and webviews, but it's worth making a backup and trying...
And yes, you have to submit it as a 3.2 app that can target 3.1.*
There are also a lot of other stuff that you have to do:
Make sure that it can be viewed at any orientation (got rejected the first time for this).
Make sure that you have all the new images created. you have to have 3 or 4 icons, instead of just one like an iPhone app needed. (iPad icon, iPhone icon, small icon for spotlight, etc).
And of course iPad sized screenshots for the store.
A really nice way that I use to test if it's an iPad or iPhone is to check if the device can use a split view controller, since for the forseeable future no device with a screen as small as an iPhone will be able to use the split view controller. I just created a function to do this for me:
+(BOOL)isIpad{ return NSClassFromString(#"UISplitViewController") != nil; }
Then anywhere in my app that I want to display something different depending on device, I just do a check for it:
int width = 150;
if([NabAppDelegate isIpad]){
width = 350;
} else {
width = 150;
}
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5,10,width,25)];
This is a lot better than checking against OS version like I've seen some suggest.