How to do this simple thing with XCode's new Auto Layout feature? - xcode

Im trying to do something that seems like it should be a no-brainer. But alas, im too dumb to figure this one out. So i need help.
I have an iphone simulator (with a vertical orientation).
The main view has a subview (a blue UIView) that should be displayed in the bottom 25% of the screen. The final rendered screen would basically look like a white screen with the bottom section being blue.
I want the edges of the subview to hug the screen edge. But thats not the part I'm struggling with. The tricky thing is configuring the height of this subview (and the layout of its contents, if any) when I suddenly rotate the orientation of the simulator. If i do this, then everything looks odd.
I would also like to note that what I see in the Interface Builder (with Auto Layout enabled) looks nothing like the app when it loads in the simulator.
PS - for now i will keep playing around with this. maybe i will eventually reach a eureka moment.
* Updated with screen shots *
This is what my layout looks like in Interface Builder:
And this is what it ends up looking like in the simulator:
* Update 2 *
Ok. After updating my post with the screenshots, it dawned on me that the simulator doesn't look like the 4" screen version (even though it does on my computer screen). After running the 4" simulator i can see the the layout just like the IB layout. But this makes me wonder why auto-layout wasn't "smart" enough to adjust for the smaller 3.5" screen.

It looks to me like you have a fixed height constraint from the top edge of the blue view to the superview that is pushing content down - conversely you may have a fixed height view above it that is smooshing things. Try pinning the top edge of the blue view to the superview and lowering the priority or changing it from an equality to a less than equal to constraint.
In IB in XCode you can change the canvas size for iPhone layouts, look for the single button on the right hand side that looks like a rectangle with arrows above and below, or inside it. In the screenshot below it is the leftmost button.

You could simply turn off Auto Layout. Springs and struts can readily make your subview 25% of the superview's height.
Or, you can certainly stick with it, but you'll need to adjust the constraints in code. There's no way to establish such a constraint in the current version of Xcode. Set constraints in IB to pin the box to the bottom of the window and fix the height, setting an outlet for the height constraint. Then in -viewDidLoad, remove the height constraint and add a new constraint to the superview which expresses the height relationship you want.
This isn't to discourage you from learning Auto Layout, but to point out that it's a bit complicated, and that the constraint tools in IB are unintuitive and relatively weak. The WWDC video Introduction to Auto Layout is a good starting point.

Related

Xcode 6.0/6.1 Interface Builder resizes views to fit whole content when clicked on the corner grip to resize

I think this is an obvious bug on Xcode 6.0.1 but I'm searching for at least a workaround. In interface builder, I have an image view that is smaller in dimensions than the image that it contains. Here is my newly created, fresh nib with just an image view, the heart image is a larger PNG file than the containing image view:
So far so good. However, when I click on the any of the grips at the corners/edges of the view to resize the image view, it immediately changes to this the very moment I click on the grip:
This happens whenever I try to resize by hand (I can resize using width/height values at inspector though) and I have hard time trying to fit my design into the nib. The problem happens both on nibs and the storyboards. Does anyone know a workaround?
UPDATE: I've updated to Xcode 6.1 but I'm still having the same problem.
The same result I've noticed when close and reopen the project. The view continues to grow up every time. I have created a simple project to search the cause of the wrong behavior of the autoresizing mask (flexible width AND align to right).
So, try to disable "flexible width/height" and "align to right". Keep the "align to left" only.
This answer is for autolayout-enabled views/nibs. For autoresizing mask solution, see Nicolai Nita's answer: Xcode 6.0/6.1 Interface Builder resizes views to fit whole content when clicked on the corner grip to resize
I've solved the problem by setting the content compression resistance priority (both vertical and horizontal) to 250 from 750. I don't know why it wasn't the case before Xcode 5 though.

Vertical NSLevelIndicator OSX

I wonder if there is a way of creating/modifying a NSLevelIndicator object so it can be positioned vertically, i.e. display discrete levels from bottom up, not from left to right, so it can be also used as element of interface-building library in Xcode?
There are lots of examples of such level displays in Apple and non-Apple OSX applications, and quite a few reasons why such an object should exist, yet how to create such an object for some reason (from what I can see in developer forums) seems either not worth asking or a "best kept secret".
Is there a template code which can be modified to into an object of such properties?
I haven't even faintest idea if such an object should really be written from scratch? Mission impossible?
Thanks in advance!
Try using
[NSView setFrameRotation:90];
it's sketchy but easier than a custom view
Edit: Alternatively try
[levelView setFrameCenterRotation:90];
SetFrameRotation:90 rotated it around the bottom left axis for me so it ended up being clipped. This one rotates it around the centre so you should be able to see it. I just made a quick swift playground showcasing it: http://cl.ly/WsL8/Vertical%20LevelIndicatorView.playground.zip
Edit again: If you're still stuck, I made a sample project with a vertical level indicator in objective-c: http://cl.ly/WrdH/levelindicator.zip
Swift 5.5.1 on macOS 11.6
myLevelIndicator.frameRotation = 90
If you need to reposition the indicator to fit within the view, realize the center of rotation is the origin of the level indicator.
So, to set the rotated level indicator 20px in from the left of the view, compute that for the new frame origin of the level indicator, not forgetting to adjust for the indicators height when it is horizontal because the original height will affect the final position when rotated.
myLevelIndicator.frame.origin = CGPoint(x: self.view.frame.minX+20+myLevelIndicator.frame.height, y: myLevelIndicator.frame.minY)
Of course, this can be avoided by placing the control in the correct position to allow for rotation within IB if that works for you. Some may not be using IB and creating these controls programmatically.

Set margins of view xcode

I have been programming android apps for a bit, and I am now making an iphone app. I want to make margins for my view. I would not like to explain my exact situation, but if someone helps me with this I'll be able to figure out what I need to do.
I have two views, I want the first view to take up the entire screen. Then I want another view to always be, lets say 20 pixels from the edge of the screen on all four sides. Is there a simple way to do that in xcode?
Thanks
I assume you're using Interface Builder (now part of Xcode).
Add the view as you suggest - leaving a 20 pixel border around all 4 sides. Set all 6 resize options (flexible height, width, top, bottom, left & right).
Ensure that 'autoresize subviews' is enabled on the parent view.
The view will now resize if the parent view also resizes, leaving a 20px margin as required.

grow or shrink UIImageView frame to fit the entire iPhone screen via AutoLayout?

So I'm still getting accustomed to the world of Auto Layout in iOS 6 and it's been a fun (or in plain English -- tough) migration coming over from strings & struts.
I have a UIImageView that's the background for a game I'm working on. Here's what a regular 3.5" Retina Display looks like in Interface Builder:
but if I change the "Size" pop-up in the Simulated Metrics field for the content view to "Retina 4 Full Screen", here's what I see:
And you can see the ugly black bar appearing along the bottom edge of the simulated iPhone 5 screen. This same ugly black bar makes it over to the compiled app running in the iPhone 5 simulator.
Are there any attributes or constraints I can apply via Interface Builder to get the UIImageView's frame to size correctly for the appropriate iPhone device screen size?
Or do I have to enter in constraints via code? (ugh)
I've watched the three WWDC videos and if the engineers covered the topic of sizing a view to fit a parent, they must have glossed over it really fast because I've haven't yet found or heard a decent method to get both UIImageView and NSImageView to size correctly to their parent views under both the iOS and MacOS side.
From what you're showing here, I think that what you want to do is drag the image to meet the bottom of the superview so that it takes up all of the space you want. On the bottom right in the IB view you will see a small, grey pill-shaped set of 3 buttons. Click the center one (once you have your imageView selected). It's the one that looks a little like this: |--|. It will bring up a list of constraints. Once you have done that, select "Bottom Space to Superview". You should then be able to switch between phones and have the image resize automatically.

Padding at top of NSView in an NSScrollView

I have an NSView as the document of an NSScrollView. I would like to have a few pixels of padding at the top and bottom of the visible part of the view, regardless of where the scroller is positioned (not just at the top and bottom of the document as described here). For an example of an app that does this, look at Terminal.app. Regardless of the background color of the text, the top two visible rows of pixels are always the default background color.
I know I could simply draw everything two pixels lower and draw a rectangle at the top and bottom of the document-visible rect, but that will require changing a lot of complex code that I didn't write. Simpler ideas are welcomed!
The answer to the question you linked is actually a good solution for this problem too. In fact if your view is anything but an NSTextView, I'd say it's easier to implement.
Specifically: make your actual document view a subview of some other view, leaving room around the edges and make that view the scroll view's document view. If your content view (the one you wish to pad) changes sizes, have your "padding view" observe it for frame changes and resize to maintain the padding.
2015 Update
Content inset has been added to NSScrollView as of 10.10, making my older answer obsolete.

Resources