Finding the center of UIImageView UIImageView.center unexpected results - ios

I have a UIImageView with the following constraints:
Height Equals 135
Trailing Space to: SuperView = 0
Leading Space to: Superview = 0
Top Space to: Top Layout = 0
The width of the UIImageView in Xcode 7.2 Size Inspector = 600.
In my UIViewController have an outlet to the UIImageView:
#IBOutlet weak var heroImageView: UIImageView!
In viewDidLoad the value of heroImagveView.center = (300.0, 67.5)
However this not the actual center of the image, 300 is way to the right of the UIImageView in an iPhone 5 simulator. Something more like (x: 160.0, y: 67.5) is center, though x is not exact.
In Xcode 7.2 the default width for all my UIViewControllers is 600 pixels, I understand that will not be the runtime rendering width across different Apple devices, but why doesn't UIImageView.center understand this?
How to I get the actual runtime center of a UIImageView?

At viewDidLoad, your heroImageView has a width of 600. Since the leading space to the superview is 0, the x position will be 0. Hence, the center is at 300.
You need to remove the trailing and leading constraints and replace them with a 'center horizontally', and a width constraint.

Related

what is wrong with constraints in my UIImageView and why I cannot stretch the image on my UIViewController?

This is my current situation:
I have a UIViewController with UIImageView on it.
The latter has the following constraints: trailing to superview, leading to superview, top space to top layout guide, width equals 320, height equals 820.
Height and width are connected as outlets to my class and I'm setting them in viewDidLoad:
#IBOutlet weak var imageHeightconstraint: NSLayoutConstraint!
#IBOutlet weak var imageWidthConstraint: NSLayoutConstraint!
#IBOutlet weak var backgroundImage: UIImageView!
override viewDidLoad(){
backgroundImage.af_setImageWithURL(NSURL(string: photoURL)!)
imageHeightconstraint.constant = backgroundImage.image!.size.height
imageWidthConstraint.constant = self.view.frame.size.width
}
Now, my image is this:
it is 480x640px photo. I tried in my storyboard to set the mode to center, scale to fill, aspect fill, aspect fit and top.
For example, this is center:
aspect fit:
aspect fill:
but I don't know how to stretch this image from left to right and keep the aspect ratio, so the whole photo is visible and its left and right edges stick to the left and right edge of the screen.
I thought those two constraints could fix it:
imageHeightconstraint.constant = backgroundImage.image!.size.height
imageWidthConstraint.constant = self.view.frame.size.width
but it does not work. Maybe the problem is that the resolution of the photo is low (480x640), so the height is only that small? Can you give me any hint how could I fix it?
To have the image stick to both sides of screen and maintain the aspect ratio, set these 4 constraints:
Leading Edge of ImageView to Leading Edge of SuperView.
Trailing Edge of ImageView to Trailing Edge of SuperView.
Top Edge of ImageView to Top Layout Guide Bottom.
Set an aspect ratio constraint: ImageView Width equal to ImageView Height with multiplier 480:640. To set this, control-drag diagonally in the ImageView and select Aspect Ratio from the pop-up. Then change the multiplier to 480:640.
Set the content mode for the image to Scale to fill.
You may not be calling setNeedsLayout() and then layoutIfNeeded().
In order for the UI to update, you need to tell the view to update, not just change the constraints.
Either way, if you want the imageView to consistently fill the screen and you shouldn't have a height/width on the ImageView, only hugging the sides. Also make sure those constraints are ignoring margins.
If you want the image to fill the imageView, set the resizing mode to aspectFill, and If you're looking for it to resize until the left/right or top/bottom reaches the edge of the view, aspectFit is what you need.

How to place a button at the center of the bottom half of the screen

I want to create a UIViewController that should be separated in two equal (in both width and height) parts.
The top one should contain UIView. The bottom one should contain the button centered both horizontally and vertically in this part:
I placed the UIView object to the right place by setting its leading, trailing and vertical space to superview to 0. I made it 0.5x screen's size by setting the equal heights for this UIView and its superview and gave it 2:1 multiplier where the first value related to the superview and the second value to the specified UIView.
But how can I place the button at the center of the bottom half of the screen?
I'm using auto-layouts and size classes.
I'll suggest you to take 2 UIViews instead 1, i.e top view and bottom view.
pin all edges of both UIViewsto 0, make equal height.
than in second UIView i.e bottom view set button to center of that view and give center X and center Y constraints along with height and width to button.
button.centerX = view.centerX
button.centerY = view.centerY*1.5
will give you what you want. You should add the width and height constraints of button as you demanded.
assuming your button superview is directly your viewController:
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
myButton = CGPointMake(myButton.superview.center.x, myButton.superview.frame.size.height * 3 / 4);
}
You can use Alignment constraints like Horizontally in container and Vertically in container. Hope this helps.
These are the steps you need to do.
1. Go to the size inspector with your UIView selected. For X and Y should equal 0. For example, Width should be 600 and height should be 300. So the whole screen is 600 by 600.
2. Select the button with the size inspector still selected. Observe the width and height values. Realize that X and Y is measured from the top left corner of the button. Now take your width of the whole screen and subtract half the width of your button, also take the height of half your screen and subtract half the height of your button. Enter these values into the position of your buttons x and y values.
i.e. if button is 50X100 (width by height) you need be at x= 300-50/2= and y= 450 -100/2=400
Swift 5 with SnapKit
customView.snp.makeConstraints { (m) in
m.centerX.equalToSuperview()
m.centerY.equalToSuperview().multipliedBy(1.5)
}

UIStackView - Distribute views evenly from the centre

I have a UIStackView,inside a UIScrollView to show dynamically added subviews horizontally arranged. Current solution will start displaying items from the left, I would like to start distributing items from the centre without changing the width and height of the subviews. How do I do that? Im also open to solutions which doesn't use UIStackView as well. That way I could support devices < iOS9.
(Current)
(Expected)
Short answer :
ScrollView constraints
Leading >= 0, Trailing >= 0, Top >= 0, Bottom >= 0
Center X and Center Y
StackView constraints
Leading = 0, Trailing = 0, Top = 0, Bottom = 0
StackView width = ScrollView width (priority low :250)
StackView height = ScrollView height
Long answer
Firstly, your structure is good, we have :
UIScrollView
UIStackView (horizontal)
Subviews
So, to reach the goal we should :
Center the UIScrollView
Set the contentSize of the UIScrollView equal to the intrinsic content
size of the UIStackView
Here is how to do it :
Step 1: Center the frame of the UIScrollView
CenterY and CenterX constraints used to center the frame of the UIScrollView
Leading Space >= 0, Trailling Space >= 0, Top Space >= 0, Bottom Space >= 0 are used to prevent the frame of the UIScrollView to exceed the frame of the parent view
I used placeholder intrinsic size to don't show errors related to the contentSize of the UIScrollView (because we don't have yet the subviews so the contentSize).
Now, the frame of our UIScrollView is Ok, go to the next step :)
Step 2: add the horizontal UIStackView
Top, Bottom, Leading, Trailing constraints are used to fix
UIStackView frame
Equal Height and equal width used to calculate the
contentSize of the UIScrollView
PS. Any change in the frame of the UIStackView, change the contentSize of the UIScrollView
Step 3: add subviews
Because we use Fill Distribution in the UIStackView all subviews must have a intrinsic content size (or height and width constraints (not preferred)).
For example, if we use Fill Equally, only one subview with intrinsic content size (or height and width constraints (not preferred)) sufficient, the other subviews size will be equal to this one.
For Example: I will add 3 labels (please remove the placeholder intrinsic size of the UIScrollView)
It works !! no, no, not yet try to add fourth and five labels :)
Why ?
To understand we will calculate the frame of each element of the view with two examples :
The parent view size : 200, 200
The first label intrinsic content size : 120, 50
the second label intrinsic content size : 150, 50
First example (only the first label in the UIStackView)
UIStackView intrinsic content size = 120, 50
UIScrollView contentSize = 120, 50
UIScrollView frame = 40, 75, 120, 50
All frames are OK
Second example (with the two labels)
UIScrollView frame = 0, 0, 200, 50
UIScrollView contentSize = 200, 50
UIStackView intrinsic content size = 200, 50
So, the UIStackView can't show correctly the two labels (because the width of UIStackView lower than the two labels width), and we don't have the scroll because, the UIStackView constraint width is equal to UIScrollView width's.
It works when the UIStackView intrinsic content size is lower than the max UIScrollView frame.
To Fix that, we change the priority of the width constraint to a value lower than the UIStackView intrinsic content size priority value, and all works fine :)
Hope that helps.
Code source

Is setNeedsUpdateContraints() ignoring me?

I have a Storyboard that uses Auto Layout & Size Classes. I've given up trying to get my UIView to use the Aspect Ratio 1:1 constraint to work. It takes over the entire screen rather than just set height = width like a UIImageViewer does.
So I am trying to change the width and height constraints instead. In IB the width constraint is set to 320 and the height constraint is set to 320. Ultimately I will set the width constraint to the width of the device and the height constraint to the width of the device, hopefully getting a square UIView for the camera to display its session.
However, when I set the constants and then setNeedsUpdateContraints, nothing happens. Yes I would prefer not to do it this way, but I would also prefer to get this &^&$^#( thing to work and not spend any more hours fighting it. Setting leading space to 0, trailing space to 0, top space to 0, and aspect ratio 1:1 does not work. Even though I did it with a UIImageView and it does work for that.
#IBOutlet var captureFrame: UIView!
#IBOutlet var viewHeightConstraint: NSLayoutConstraint!
#IBOutlet var viewWidthConstraint: NSLayoutConstraint!
override func viewDidAppear(animated: Bool) {
self.viewWidthConstraint.constant = 100 //100 = temporary
self.viewHeightConstraint.constant = 100 //100 = temporary
captureFrame.setNeedsUpdateConstraints()
captureFrame.layoutIfNeeded()
}
Any idea how to get a square UIView so that the camera can be displayed in it using IB, auto layout, size classes AND not have it zoomed in X2?
Why aren't my constraints adjusting to 100? Why is my UIView still 320 x 320?

How to resize a view to fit a label subview using auto layout?

I'm trying to make a translucent black rectangle with some text in it, to convey some info to users. It seems to work, but when the phone's text size is large then the label's contents are cut off -- the view won't expand its dimensions.
To create this I added a UIView with a black background and rounded corners, made it somewhat transparent, and placed a UILabel inside it. Constraints on the view should allow it to grow wider when the phone is rotated, and constraints on the label keep its edges pinned to the view.
Here are the view's constraints:
Align Center X to: Superview
Align Center Y to: Superview
Trailing Space to: Superview >= 40
Leading Space to: Superview >= 40
Width >= 200
Width <= 300
Height >= 100
Height <= 150
And the label's constraints:
Trailing Space to: Superview Equals:Default
Leading Space to: Superview Equals:Default
Bottom Space to: Superview Equals:Default
Top Space to: Superview Equals:Default
When run on an iPhone 5, the view's size is 200 x 102 for some reason and the text is truncated, even though its constraints allow it to go up to 300 x 150. What am I doing wrong?
Just set UILabel Top/Bottom/Lidding/Trailing constraints to zero because it has intrinsic content size. It means label will wish to become that wide to contain its string value all visible. Look at this article
Create constraint programmatically
_constraint=[NSLayoutConstraint constraintWith...];
[self.view addConstraint:_constraint];
//...
_constraint.constant=40;
Use outlet if all the constraints are defined in IB. Just connect it to your constraint.
#property (nonatomic,weak) IBOutlet NSLayoutConstraint *constraint;

Resources