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

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.

Related

Aspect ratio constraint is not working for UIStackview with nested UIstackviews

I have a view controller with six buttons.
I want to show them in 3 rows and 2 columns.
I decided to put each column of buttons (3 buttons) in a stack view and put 2 vertical stack views in 1 horizontal stack view.
I want my buttons to look square shaped.
I applied following constraints for the horizontal (main) stack view:
Align Center X to Safe Area
Align Center Y to Safe Area
Align leading to Safe Area Equals:50
Aspect Width:Aspect Height = 2:3
For some reason aspect ratio is not working and the width is still
larger than the height and more importantly the buttons are not square shaped.
I tried to update frames, to apply all possible alignment and distribution properties, however, it didn't solve the problem. Please check images below for your reference.
View Controller
Constraints
Thanks in advance!

How to set different color for upper and bottom area which is outside safe area in iPhone X

How to set a different color for the upper and bottom area which is an outside safe area in iPhone X i.e for point 1 and point 2 in the image?
If I set the color to main view (point 3) then it gets applied to the whole view. I want to set the different color to an upper area of the safe area, to a safe area and to below bottom safe area.
add two views and give background color to them. if its not required in other view set hight 0 point of both view.

How to adapt the position of a UIButton to a background image for all iPhone sizes?

I just begin swift and I'm facing a simple problem:
I can't adapt a UIButton to an image in my storyboard for all iPhone sizes. I work with a storyboard with the size of an iPhone 6s Plus because I have one. When I run my test, all it's OK but when I run my test with iPhone 5 simulator, nothing is good.
This image shows the button is in the good place on iPhone 6 plus but no to other sizes.
I tried so many different constraints but nothing seem to work.
In summary: How can I set constraints to position a button at the circle in the background image (as shown in the linked drawing), regardless of phone size?
Try setting your constraints to a percentage.
Control-drag from your button to your view.
Shift-click to select Horizontal Spacing and Vertical Spacing.
Click Add Constraints.
Now, you should have 2 constraints for the button, relative to the superview.
In the Attributes Inspector for each constraint, check to ensure the button's X and Y are relative to the trailing edge and bottom of your superview. For example:
First Item: Button.Center X
Relation: Equal
Second Item: Superview.Trailing
First Item: Button.Center Y
Relation: Equal
Second Item: Superview.Bottom
In each constraint, set the constant value to zero.
Then, set the multiplier value to a percentage or fraction.
For example, if you want the button to be at the halfway point, regardless of device size, enter a multiplier of 50% (or 1/2 or .5 if it won't take the percent value - sometimes it won't accept one version of a value, but it will accept another expression of the same thing).
The percentage is multiplied by the superview's values. The superview's trailing edge is the max X value, and the superview's bottom edge is the max Y value.
Your button appears to be around a third of the way down the view, and about a quarter of the view on the left. So you might try setting the Button.Center X multiplier to 25% or 1/4 or .25, and the Y multiplier to 33% or 1/3 or .33
Note also that under a constraint's Second Item dropdown, you can select whether the value is relative to the margin. If that is not selected, the multiplier uses the full width or height of the superview. Selecting Relative to margin uses the width of the superview minus any trailing or bottom margin. That could throw off your percentages. I recommend leaving Relative to margin unselected when playing with your values.
Here are images for the end constraint values:
Note that the button doesn't seem to be centered until you look at the preview. Running the simulators for the different sized phones gave me the same results as shown in the preview: button correctly centered in the circle.

make four buttons width to fit for all screen size in swift

I am doing a sample project with size class and autolayout in swift.I have four buttons on top of the screen.How to set same width for all buttons with one pixel gap between them and make them fit for all screen size.
thanks in advance
The trick here is to make the button widths variable, but the same for all buttons. This can be accomplished like this:
Place the four buttons
Set the left margin constraint from the leftmost button
Set the right margin constraint from the rightmost button
Set horziontal distance constraints between the buttons to 1
Set the width constraints for all buttons to >= 10 (or any other
value, this makes the width variable)
Set equal width constraints on all buttons (ctrl-drag from one button to the next and choose equal width. Repeat that for all buttons)

Increase UIView's frame size at the left edge

I have an UIView that can grow dynamically in width. The view also have subviews located inside it's bounds.
Default behavior seems to be that when the view's frame grows along the x axis, increasing frame.size.width, it always grows at the right edge, keeping the subviews fixed as if there were a fix left margin. However, when I want to expand the view on the left edge this doesn't work because of this behavior. In this case I want it to behave in a mirrored way, as if there were a fix right margin. I could of course "manually" move all subviews so it looks like that is the case, but that seems really awkward since there could be plenty of them.
So I guess the question really is if there is a way to shift a views bounds relative to it's subviews? Is maybe autoresizingMask the way to do this?
Thanks.
Maybe you should take a look at the AutoresizingMask property of a UIView subclass :-)
For example, if you have a UILabel called labelVideoTitle, you could set a mask like this :
[ labelVideoTitle setAutoresizingMask:UIViewAutoresizingFlexibleWidth ];
You can by the way add 2 mask at once like :
[ labelVideoTitle setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight ];
Good Luck !
Edit : To increase the parent view frame size at the left edge, you could change too its X position to the left to give the impression wanted ^^ For example if you add 10 pt to the width, try modifying the X origin -10 pt :-)
In interface builder, you can graphically indicate in the CMD-3 (little ruler icon) Size Inspector what each element in your view should do when the parent view is resized: you can indicate which borders (top, left, right, bottom), the given element should "stick to" when the parent view is resized. You can also indicate whether the given element should itself resize (in either width or height) or stay the same size. Underneath the hood, this sets the autoresize mask for the UIView element you're editing, but especially for making an element stick to a particular border, Interface Builder is the way to go.
IB Size Inspector also has a neat little animation that shows you the effect on a hypothetical element (little red square) during a resize, given your settings to the left.