how to add diagonal strokes to a UIView - iphone

how can i add an X looking red stroke to a UIImageView.
i would like to add 2 diagonal red lines to a UIImageView, is there a way to do it programmatically using layers or masks? (not in drawRect)

Use a CAShapeLayer with your X shape as its path. Depending on how you've drawn the path, you may want to set a nil fill colour (since a path just made of two crossed lines should not be filled).
Add the shape layer as a sublayer of your image view.

Related

How to get exactly the same point on different screen sizes?

I want to call the action (go to another view) when user tap specific area of image (black dots): . Image fills whole view, content mode is 'Aspect Fit'. The problem is that when I setup it on one screen size (e.g. iPhone 8) on another the 'tap area' is shifted. I've tried to solve this with button and constraints or UITapGestureRecognizer with point conversion using screen resolution (nativeBounds), but nothing helps.
It is possible to use constraints to match the positions of the circles with UIButtons. The trick is to use the multiplier of the constraint to scale the buttons width/height and position to the screen size.
I'll describe how to do it for one button, and then you can repeat it for the others. I assume the image is 657 wide by 918 high. If I have the dimensions reversed, you'll need to substitute the actual values for the ones I have used.
Create a UIView to hold the image and buttons. Give this view an aspect ratio constraint with multiplier 657:918 which is width:height. Add the UIImageView to this view and constrain its 4 edges to the edges of the view with 0 offsets. Give this view constraints to the left and right edges of the main view and give it a vertical constraint to place it on the screen.
Get the width/height of the circle in the image and the horizontal and vertical positions of the right edge and bottom edge. For example, the topmost circle is 106 x 106 and ends at horizontal position 392 and the bottom is at 338.
Set the width of the button equal to the width of the containing view with multiplier 106:657 which is width of circle:width of the image.
Set the height of the button equal to the height of the containing view with multiplier 106:918 which is height of circle:height of the image.
Set the trailing edge of the button equal to the trailing edge of the containing view with multiplier 392:657 which is end of circle:width of image.
Set the bottom edge of the button equal to the bottom edge of the containing view with multiplier 338:918 which is bottom of circle:height of the image.
This will allow the button to stay aligned with the circle on all devices. Repeat steps 2 through 6 for the other circles.
Instead of using an image, you can try creating your own UIView subclass called BlackDotsView.
In the draw(_rect:) method, you can draw the lines. To determine where the lines start and end, you need to do some maths with the view's width and height. You calculate where all the lines end and create UIBezierPaths and then you stroke the paths.
In the initializer of BlackDotsView, you can add the dots as subviews. To make them circular, just set dotView.layer.cornerRadius to half the dot's width. Then, you can add UITapGestureRecognizers to the dot views.
You can follow the delegate pattern by creating a BlackDotsViewDelegate that has a method called dotTapped(index:). When a dot is tapped, you would call the delegate method and pass the index of the dot.

Getting the outer CGRect

I have two UIViews, both of which obviously have CGRects each. One UIView fills the screen whereas the other just fills part of it in the middle. I have the CGRect of the smaller UIView, but how can I get the CGRect of the one outside of it - excluding the size of the smaller one so that the background can be dimmed, but not the content of the inner UIView?
This is what my UIViewController looks like so you can get a better idea of what I'm trying to do:
I want to dim the outer UIView, not the inner one - but I don't have the CGRect of the outer one excluding the inner UIView so I've had to do it the other way around for now.
A CGRect is a square size. If you want to know the outer aria you need to compute 4 CGRects. The top, left, right and bottom space.
So, it looks to me like the outer view is responsible for drawing your content and the inner view is your selection rectangle right?
If so, then I think you are going to want to draw your content twice when you have this selection mode active. You will:
draw one pass dimmed - adjust the colors yourself (you can either draw the whole area or clip away the inner area using code from here)
draw the second inner pass with a clip rect setup so only your content inside the rect for your selection rectangle is drawn
Or
draw all your content like normal
set your clipping mask (using code from here so that just the outer area is rendered) and then draw a black rect with some degree of transparency over your whole scene

How to create a graph-paper kind of layout?

I am making a custom View where I am plotting a curve. Now I want the background of that curve to be like a graph paper.
shall I use a vertical and horizontal lines Or draw a series of rectangles Or use background image?
currently I am using vertical and horizontal lines but the problem is even when I am setting the thickness of the line to be 1 pixel, It still seems to be thicker and If I reduce the thickness to say 0.5 then the color becomes lighter than what I have set it to.
For this kind of thing, if you don't expect to have to make many, many dynamic changes to the background image, you could just use a carefully-crafted .png. You can even make the thing a single square and then use
view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"template"]];
Although, if you're doing plot work, then you may want to draw the lines manually as you are. The answer to your question then is to make the stroke width 1.0 but to draw the lines at the halves: so to draw a vertical line down the 100th x pixel column, move the cursor to (99.5, 0.0) and stroke to (99.5, 480.0). CoreGraphics drawing routines draw your stroke centered on the theoretical line you create, and will antialias to physical pixels as necessary.

Creating a stroke/outline of a .PNG with CALayer?

I would like to apply a "stroke" or outline to a png, identically to how Photoshop does it. I have a feeling this can be done with CALayer, but after some tinkering, it is not immediately obvious. setBorderWidth + setBorderColor is almost what I want, except that it only adds a border to the entire dimension of the image, rather than the outline of the png image itself.
Once the stroke is applied, I'd like to also knockout the fill of the png, leaving only an outlined border of the initial shape.
There is no automatic way to do what you're asking. You have to know the path of the shape within your png that you want to "knockout". Once you've defined that, you can create a CAShapeLayer, which accepts a CGPathRef, containing your points. You can stroke and fill the path layer with whatever color you choose and then add it to the layer hierarchy of the displaying view or use it to define a mask of one of the layers in your view.

How do I use a mask to punch out my image?

I have a mask (loaded from a 256 grey PNG) that I want to apply to an image that's being used as part of my process for drawing a UITableViewCell's imageView.image property.
When the cell isn't selected/highlighted, I CGImageCreateWithMask with a square of the proper color and the mask, then drawAtPoint: it into the image I'm building. This works fine.
However, when the cell is selected or highlighted, I'd like to instead use the mask to instead punch through my image appropriately. That is, when my mask specifies full opacity, I want the image I'm building to be completely transparent so the tableview's background is drawn through it. Where my mask specifies 0 opacity, I want the alpha channel untouched. I want nothing other than the alpha channel affected.
I guess what I mean is that I want to draw clearColor over a UIImage, with a varying level of opacity according to a mask.
First, what is this called? And second, how do I do it?
I think you have to manipulate the CALayers for that. You can use the mask property of the cell's CALayer : CALayer mask attribute.
That is, something in the way of (if myMask is descendent of UIView) :
myCell.layer.mask = myMask.layer