AutoLayout: different OS X versions, different behaviors? - macos

I'm developing an app for OS X which shows a small window (uses Auto Layout) when exiting. The window's size is about 550 x 290 pixels and it's fixed.
But I'm facing a behavior that seems pretty strange to me:
Starting the app on OS X 10.7: the size of the small window is about as triple as large as it should be (width and height)
Starting the app on OS X 10.8: the width of the window fits but its height is still about as twice as it should be
Starting the app on OS X 10.9: the window has the size as I've designed it
Starting the app on OS X 10.0: same (correct) behavior as with 10.9
I've re-set all constraints to correct settings (Xcode shows no layout issues). Can somebody give me a hint what might be happening there?
I'm absolutely sure that there are no other (conflicting or modifying) constraints within the view.
Update
Below you can find an image containing all constraints of the window. The constraints of the window itself (min and max size) have been set to the current (expected) size.
The image on the left side has been pinned to the bottom, the left and the top and its scaling behavior has been set to proportionally down. So the image should not be the source of the issue.

I've found a solution that works. I think it was a combination of the 2x image within the assets catalog (caused the doubled height) and the labels within the view. The labels contain so much text that they either have to wrap it automatically or stretch them until the content fits (Lion and Mountain Lion seem to do so).
I've added the width constraint to both labels and fixed it at its current value (as given in the Interface Builder). This works for me as AutoLayout seems to keep the label's width and wraps their content (as expected).
Thanks a lot for the hints.

Related

Auto layout Simple X Y constraints for Container View not working

I am following a simple tutorial trying to add an X and Y constraint and am having issues with it.
Here is the tutorial:
https://www.youtube.com/watch?v=emojd8GFB0o
Around 11:07 he adds an X constraint and a Y constraint.
I did exactly what he did except for am trying this on a Container View. and yet I still get error saying that it needs an X and Y constraint. It works perfectly fine on a button.
Please help! What am I doing wrong? How do I get this to work on a Container View?
Buttons have something called an "intrinsic content size", which means they can tell the layout system what their preferred size is, this is calculated from their content (text + image).
Your empty container view has no intrinsic content size, it cannot know how big it is on its own, and so far it only knows it has to be centered in X and Y.
But that's not enough to know its X and Y position (the position is the coordinates of the top-left corner), because if, for example, the width is the full width of the parent, X would be 0, but if the width is 0, X would be half the width of the parent.
You need to give your view a width and a height, whether you do this by linking its size to the parent, or by using constants, that's up to you.
A UIButton knows how big it's going to be in size(width,height). Try adding a short/long title value to the button and you will see that it will size itself accordingly. So when you add centerX & centerY constraints to button (relative to it's superview), Autolayout can do the rest of the math.
Example - Button is 60x40 and it needs to be in center of the screen both horizontally and vertically.
A UIView does not know how big it's going to be in size(width,height). In this case specifying centerX & centerY is not enough for Autolayout to do the rest, it can't guess the size of the UIView and hence it can't calculate where to place your view on screen (without knowing size).
You can add width & height constraints to your view and you will see that Autolayout will stop complaining about this.

NSToolbarItem with Segmented Control - Images Not Rendering Correctly

I'm trying to emulate Xcode's toolbar controls to show/hide the Navigator and Inspector:
...but without the bottom pane (only left and right: two segments)
I screen-captured the icons from Xcode's UI and traced them in an image editing application. The resources for the left pane are:
#1x:
(20x20 #72 dpi)
#2x:
(40x40 #72 dpi, although using 20x20 #144 dpi seems to make no difference)
The right-pane counterparts are identical, but flipped horizontally.
All rhe resources are stored in the asset catalogue, as follows:
I dropped a segmented control on the toolbar, to create a toolbar item with a segmented control inside it, and set the image attribute for each segment (0 and 1).
Image Scaling for both segments is set to "Proportionally Down". The segment control has segment width "Fixed" checked, with a width of 48 for both segments. The toolbar item has Minimum Size of (83 x 25) and Maximum Size of (100 x 28).
The icons display correctly on the storyboard (Interface Builder).
However, when I run the app, I can not get the icon images to display appropriately.
If I launch my app on a retina monitor, no icon is displayed on either segment.
If I move the window to the external, non-retina monitor, both icons are displayed.
If I remove the one of the two image sets from thew catalogue and run the app, the other icon is correctly displayed! (on either monitor)
If I further set the same, remaining image for both segments, they display correctly!
If I leave both image sets in the project, but reset the Image field in one of the segments to empty, the other icon isn't displayed eihter!
What on Earth is going on??
I have put a sample project on GitHub that reproduces the issue.
Edit: Just to make sure, I extracted the resources from the compiled app binary using the cartool command line utility (as explained in this answer), and all 4 images are there at the right sizes...
Solution: As suggested by Ivan's answer below, I switched to using vector graphics (PDF) for the icons. I downloaded the trial version of Acorn and recreated my icons at 1x size, then exported as PDF.
To avoid blurring at the scaled up size of #2x at runtime, I had to make sure all coordinates in the editor were integers, and also check the box for "Snap to pixels" in the Vector Shapes inspector for each shape layer:
(Happy Ending)
$ git commit -m "Fix toolbar icons for good (PDF)"
According to my experience, using of bitmaps in toolbar is troublesome. You can try to target exactly recommended resolutions to possibly avoid some problems: https://developer.apple.com/macos/human-interface-guidelines/icons-and-images/custom-icons/
However, the cleanest way would be to use vector (pdf) icons, as they simply work as intended.

How do I get the auto-layout to work correctly in xcode?

I am attempting to get the auto-layout to work correctly. For some reason, when I change the size of the device, all of the images and buttons are out of place and don't resize at all. This is true for the 3.5 inch screen, as well as the ipad retina. When I run the simulator, the app shows exactly how it shows in storyboard. Auto-layout should be resizing everything so that this does not happen. please help!
The issue is that constraints don't scale. When you set a constraint height to 200 it will always be 200, even if the screen is only 100 high. So what you need to do is try to set constraints that makes the size dynamically rather then set the constraint height/widths yourself.
For instance, on your first label under the UIImageView set the constraints leading and trailing to 20, then set the label constraint to center horizontally on the UIImageView. No other constraints for the label. This will cause the label to shrink in width since its set to be 20 away from each side. The height will not change since there is nothing "pushing" it to shrink since you are missing a few constraints, but basically you need to use the top, bottom, leading, and trailing, constraints to the UIViewController view in order to "scale" the elements.
If you'd like I could try and set the constraints for you if you upload the project and you can then watch how I did.
Edit
It's hard for me to know what kind of behaviour you'd want, but something has to scale or change size in your set up. The easiest would be to resize the UIImageView. It's basically impossible to make it look exactly alike in every screen size, though, so you'll have to play around a bit with constraints until you understand how they work and how to adjust them according to what you want. One way is to create the layout you want and then connect them to code and scale them depending on size of the screen (this is a bit of a pain, I did that in a project recently and it took a bit of time and effort).
The easiest approach is to make the UIImageView to change its size when it needs to, and add extra space in the bottom. Here is a demo project I threw together earlier. Download here
Profile pic
1) first you set the profile pic image center horizontal to the content view
2) set height and width for the profile pic
3)set top space constraints to content view
Change Profile pic label
1)set central horizontal to profile pic
2)set width and height
3)set vertical space between profile pic
Challenges Accepted label
1) set vertical space to profile pic label
2) set Leading space to container
3) set height
and do same for the below two content . i didnt tested. check it and try
After a long night of struggling, I figured out what I needed to do. I was setting the individual view controllers to have a simulated size of 4.7inch. This made it hard for the constraints to scale across all devices since I was setting the constraints for a specific screen size. However, this would be the way to go if using size classes.
I solved my issue by using the standard 600 X 600 canvas that is available before choosing a specific size. This way, I was able to set constraints that scaled down for the smaller screens, and scaled up for the larger/HD screens. This works perfectly with auto-layout. Hope that helps someone!

Xcode: difference between BACKSPACE + CMD and BACKSPACE?

I don't understand the difference between using BACKSPACE+CMD and just BACKSPACE.
I see that when I use BACKSPACE+CMD on a element in the Storyboard, that element becomes opaque, and using just BACKSPACE it deletes the element. I can't find the answer in the documentation.
As far I know, when opaque, it means the component (constraint or UI element) has been unistalled for a particular size class. For me, the combination is Command + Delete.
From About Designing for Multiple Size Classes (in bold the key part).
With size classes, a storyboard or xib file can be used for any
available screen area. You build your interface as it will look in
most sizes, then update only the parts that need to change when the
available screen size changes.
A size class identifies a relative amount of display space for the
height and for the width. Each dimension can be either compact, for
example, the height of an iPhone in landscape orientation, or regular,
for example, the height or width of an iPad. Because much of the
layout of an app does not need to change for any available screen
size, there is an additional value, any.
Hope it helps.
P.S. Did you check the key binding for your Xcode?

Why does this text look "less bold" in OS X 10.5 compared to 10.7?

I built a very simple application with nothing but a single NSTextView in it in xcode / interface builder. I've done nothing to the text view other than change the font face to "Arial" and increase the font size. However, it looks a lot less bold on OS X 10.5 than it does on 10.7. What's going on here?
(10.5 in the top window, 10.7 in the bottom window)
I've tested with Helvetica and got the same results, so it's not something to do with this specific font.
If you enlarge that image enough, you'll see color fringing on the 10.7 sample. This indicates that the text was rendered with subpixel antialiasing, more specifically, using a RGB subpixel ordering. The 10.5 sample uses grayscale antialiasing. While it is generally a good idea to use subpixel rendering, it can look bad on low-resolution screens or CRTs, and it can't be used in a multi-monitor setup where there is more than one subpixel arrangement to contend with. This means that some users will have subpixel rendering enabled for their system, and some won't. Don't try to circumvent that setting in any way, either by overriding the system preference for font smoothing, or by pre-rendering the text into an image. Users are far more likely to notice the one app whose text looks wrong on their system than they are to notice the difference in rendering between two different machines.

Resources