clipsToBounds only verticaly - ios

I would like to be able to set clipsToBounds at NO for an UIView but only with the horizontal component.
My content will be displayed on left / right even if it's too large but top / bottom will not be displayed beyond the container's height.
Should I use maskToBounds layer property and add a specific mask ?

You should start by asking yourself why you think you need this. If you want to display the horizontal content when clipsToBounds is YES, why not make the view big enough horizontally? It can go right off the screen on both sides, no problem. A view that is visible when it is not inside its superview is usually a very bad idea in any case (for example, the user can see it but can't touch it, which is usually undesirable and confusing).
Otherwise, this is going to be a very tricky problem. You will probably need to put another view above your view and another view below it, to cover the content that sticks out above and below your view. Crude but effective.

Use UIView's mask property. See documentation
The mask view's width can be maximal, and the height can be the same as the view itself.
maskToBounds needs to be false in this case.

Related

Difference between UIView.layoutMargins and AlignmentRect

I'm figuring out (again) how to set the margin for a custom UIView instance. From what I recall I had to set the AlignmentRect via the alignmentRectInsets method. But that did not worked with auto layout.
Searching on google I found that there is another property called layoutMargins.
So the question is what does layoutMargins and alignmentRect do ? Do they affect each other? Totally different things ?
layoutMargins determines how things inside of the view are positioned with auto layout. Usually this is used to keep objects a specific distance away from the edges of the view.
alignmentRectInsets is for telling objects outside of your custom view how they should align with it. For example, you might have a view with a wavy or angled top. Aligning other objects with the top of the view may not look quite right, so you might set an inset on the top alignment to compensate.
You probably care about the layoutMargins. I've never actually seen anyone use alignmentRectInsets.

How do I make two equally sized imageviews cover the whole screen

I implemented a viewcontroller similar to the one in this question:
iOS two views cover exactly half of parent view
I get the desired result. The problem is that when I add a UIImageView into those two containers, the result get resized and ruins the symmetry. How do I prevent Imageviews from changing the size of their containers? I need to use AspectFill for these images.
I don't think the containers' sizes are changed. You just need to set their clipsToBounds property to true to avoid overflow.
If you use Reveal you should see the containers' sizes are not changed even if pictures inside them are bigger than themselves.
I'm unsure I understand what you mean about adding UIImageView into those controllers causing the views to resize, so forgive me if I'm getting this all wrong...
It sounds as though you've created two views of equal height that, together, consume the entire vertical space of the screen. After having done that, you want to add one or more UIImageView's to each of the original two views. Unfortunately, when you add the UIImageView, the enclosing view is resized.
Assuming I have that correct...
Are you doing this with Interface Builder either in an XIB or Storyboard file? If so, you ought to be able to achieve this with the proper set of constraints.
In the following image, I've laid out what I describe above.
As you can see, I have a red view on the top half of the window and a green view on the bottom half. The red view contains a UIImageView that is 75% of the width and height of red view, with its origin at (20, 20) within the red view.
The scene is configured as shown below:
The constraints on "Upper View" are:
You can see from this that Upper View is flush with the left, right, and top of its superview, and that its space to Bottom View is 0. You'll have to trust me that Bottom View is set up the same way.
The height of the Upper and Lower views is "Proportional" as shown in this constraint:
To achieve this "Proportional" setting, you first make the height of Upper View equal to the height of the superview, and then edit the constraint, changing "Multiplier" from "1" to "0.5."
The height (and width) of the Image View is proportional to that of the Upper view, as shown here:
If you set it up this way, you ought to be able to accomplish what (I think) you are looking to accomplish.
If my original assumption of what you are trying to achieve is incorrect, please post images of what you've got and how it's not working.

changing property contentsGravity in transform-only layer, will have no effect

I started to create a very simple tic-tac-toe game.
The main goal is to make the view proportional to all screen sizes of all iOS devices.
So I put the image on a ViewController, make it full size of screen and then I put it into a Stack View. I've added constrains to this Stack View 0 to all sides.
And when I ran the simulator then everything looks good. But I receive a message in console panel. What does it mean?
It could happen because you changed the Mode attribute of the StackView:
I got this warning when I set Mode to Aspect Fit.
Any layer change on a UIStackView will result in this warning. As the warning points out UIStackView is a transform-only layer and it differs quite slightly from a UIView. As per documentation:
The UIStackView is a nonrendering subclass of UIView; that is, it does
not provide any user interface of its own. Instead, it just manages
the position and size of its arranged views. As a result, some
properties (like backgroundColor) have no effect on the stack view.
Similarly, you cannot override layerClass, drawRect:, or
drawLayer:inContext:.
More on this here.
It may not point to the exact source of the OP's issue but hopefully, it will shed some light on why UIStackView behaviour is not the same and should not be confused with UIView.
For someone that need: I set clipToBounds to false in StackView.
It looks like what you did is perfectly correct.
However, I'm wondering why you chose to put your imageview into a stackview when you could have just as easily pinned the sides without the stackview. I am a big fan of stackviews but they don't make sense everywhere. Unless you're planning on adding new views, and resizing your ticktactoe board, I might not use it.

Best practical way to draw line over UIImageView?

I've been reading a lot of posts here and I see conflicting information.
I'm trying to draw a line over a UIImageView which already contains a picture.
I'll need to draw the line either horizontally, vertically, or not at all based on user selection, without disturbing the existing picture.
Some responses say to draw into the UIImageView directly, some say to subclass a UIImageView or UIView, and still others say to create a view layer.
What is the Best Practice for this, and can you also point me to a tutorial?
Since you need to pan/zoom the image underneath, I suggest you implement a stack like this:
[UIScrollView] on the bottom
[UIImageView] inside the scroll view for pan/zoom
[UIView] on top of the scrollview - for drawing the line
(see this tutorial for line drawing).
Personally I've used this project for implementing pan/zoom -- it's well implemented and takes a lot of the guess work out of it.
The easiest way to do this, since you only want to draw a horizontal or vertical line, is to add a subview to the UIImageView. If you want a horizontal line, set the subview's height to 1-2 points and set the width to the image view's width. If you want the line to be vertical, set the subview's height to the image view's height and set the width to 1-2 points. Set the subview's background color to whatever color you want the line to be.
A subview always appears on top of its superview.

Set UIView height based on inner view height using constraints

I have one UIView and inside that, N UILabels which are laid out relative to each other.
The containing UIView has a background color, I want to extend the UIView to be high enough to cover all labels inside it, so the background color is behind them all.
(I'm embedding them in a UIView so I can have the labels inset from the view edges.)
Is there away to make the UIView's height expand to fill its content? I can't figure it from the constraint options, it seems like its all relative to superviews.
Normally I'd just work out the frame sizes programatically in viewDidAppear but those are getting reset by the constraints system, AFAIK.
I think I actually worked it out though.
I had the labels height set manually from when I drag-dropped and resized it. Deleting the height constraint on the UILabel made it size to fit content, which causes its superview to resize too. At least I think that's the case, I'm new to constraints.
Will leave the question up since it will probably bite someone else too.

Resources