Have xib's size conform to contents? - swift

I'm creating a xib for a custom view of mine. I want the main part of the view to be 44 pixels high, with a 4 pixel shadow below it, and have the width fit the contents of the view. Right now, I have my xib's Size set to Freeform.
But my problem now is that my xib is 500x500 pixels, while my view is meant to only stretch to the width of its contents and its height should only be 44 pixels.
How can I make it so that the xib's size changes according to the views inside it?

Freeform views won't automatically resize in the interface builder from the autolayout constraints of its content; they do at runtime if you set your constraints right.
If the size of your view in the IB mismatches your constraints' description, you'll get a conflicting constraints warning that won't affect the way the view is displayed during runtime. You can remove them by manually resizing the frame in the IB so all constraints are satisfied.

Related

Why do StackViews not have intrinsic content size?

I've always wondered why UIStackviews don't have an intrinsic content size? What is Apple's reasoning for not having them calculate the intrinsic content size like a normal View does?
I use stackViews in autoresizing tableView cells, and I usually have to custom subclass the StackView to make the intrinsic content size be calculated correctly.
It does has an intrinsic content size for distribution type .fill but this needs the subviews to have intrinsic content size like label and button , otherwise give them a height , also make sure that you hook constraints properly from top to bottom inside the cell

UIImageView masks and bottom alignment

I am working on an app that has TableViewCells with varying heights. I am placing a UIImageView into them and each will use the same size image (the same size of the largest cell), however I need to mask the excess in the smaller cells (keeping the bottom, not the top).
To be more specific, I have 3 different cell heights, 112, 104 and 88. The images will all be 112 tall and I want the images to have the tops cut off on the smaller cells. Im pretty sure the answer lies within the bounds, frame and center attributes of a UIImageView, but I cant figure out exactly what I should be doing.
You will need to set the frame of your image view such that the bottom of the image view is aligned with the bottom of your cell.
You will also need to ensure the contentview of you cell is clipping content to its bounds (setClipToBounds to yes).
If I had to do this I would subclass the UITabelViewCell class and implement the layoutSubviews method. In your implementation don't forget to call super first so the content view has the right size (also if you go in editing mode). Then use the content view bounds and place your content accordingly.
When you add the image view to the cell, it should automatically cut off the top part, as long as you have the UIImageView bottom positioned within the frame, it should be what you wanted.

Is it possible to set autosizing in interface builder for rotatable bg image?

I'm designing the UI with IB with a lot of images, and the default design orientation is landscape. However, I need to shrink the whole view to fit in portrait mode, by shrinking to the maximum allowed width and maintaining same aspect ratio for the view with it's inner images. The best way to imagine what I want to achieve is to imagine some landscape photo. When you rotate that to portrait it shrinks to the maximum width, centers vertically, but maintains the same aspect ratio. In my case, I want to shrink a view with its all inner subviews.
First, I'm manually resizing view frame to required size in viewWillApppear, and also calling setAutoresizesSubviews to resize all it's inner views. Those inner views - images are with "Aspect Fit" and all autosizing options set (to fill the available area on resized view). However, inner views pops out of the container: some images jumps to the top, text view expands to full portrait height. Is possible to set some kind of "view-container", then say - "view resize to size X and resize all your but only inside view-container area?
When you design in IB you must check several things. First of all the "view container" properties, that is the view that contains all subview. In order to behave properly on rotation this view must be setup with right IB Autosizing properties, that is with the autosize lines (springs) and border lines (structs) correctly set. In your case you want your container to be exactly fit with the main view so enable the "structs" at the four sides and enable the "springs" inside. Play with this values and look at the "Example" displayed by IB.
Then you must instruct this container to properly behave with its subviews. So check in IB that "Autoresize subviews" and the content mode, if needed, (= "Mode") has the wished setting.
At this point you check in the device or the simulator if your view is rotating and rising properly.
Then you must take care of the content of this view, which is a UIImageView. This must be centered, so remove the structs, and autoresized, so set the springs. Then set the content mode to Aspect Fit or Aspect Fill at your wish.
These settings should work. For more complex stuff, you must programmatically set things.

Dynamically set UIView size depending on height of grouped table view

Setup: I have a UIView with a scroll view nested within it. Within the scroll view I have a label, uiimage, and a tableview (grouped). The label, uiimage, and tableveiw are populated by a webservice. The last section in the grouped table view contains text that will never be the same and could be as long as 5 characters to 250+. Also, this view is pushed from a basic tableview (so it has a navigation bar. If that matters at all).
Expected: The uiview should extend in height depending on the height tableview extends to. Then I will be able to set the scrollview to accommodate the height I need to be able to scroll.
Problem: I'm not quite sure how to approach the issue. I really only know how to change the height to fixed values, which will not work properly in almost any scenario.
Am I using UIScrollView incorrectly? Do I need to resize the UIView at all?
You don't have to modify your UIView frame size, which has to be the size of your screen. The UIScrollView frame size must also be the same, it represents the part of its view actually displayed.
What must change is the UIScrollView contentSize, which defines height and width for data inside it ;)
You can calculate it using each inside element's height and by adding the correct margin.
Thus, you could have a UIScrollView content size of 320 * 600, which will let you automatically scroll down.
In fact, you have to display your content independently of the final frame size. If you have a content of 500*500, just display it inside your UIScrollView. Then tell it the size of it's content, and it will automatically set scrolling possibilities if needed.
Turns out I had to create a UIView programmatically and set it as the header of the UITableView. It works perfectly now. :)

How to auto-resize UIView proportionally?

I have a UIView whose height should always be exactly 1.5 times the width. When the view is auto-resized (in this case, because the iPhone is rotated), this proportion gets messed up. How can I make sure the height/width ratio doesn't change as the view resizes?
You need to set the views autoresizingMask property to UIViewAutoresizingNone. This will prevent the size of the view from changing at all when the parent view's size changes (such as when the phone rotates.) If you want the view to resize on rotation, but maintain it's aspect ratio (for example if you want it wider in landscape but still 1:1.5), then you will need to set the view's frame yourself to the desired dimensions (but maintaining the desired ratio) in the view controller's willRotateToInterfaceOrientation:duration: method.
You could implement the -sizeThatFits: method for your view to keep the size in proportion.
Alternatively, you could use a custom superview that implements - (void)layoutSubviews to have complete control over the layout.