How to make a UITextView fill up the remaining space - ios

I have a UIButton and UITextField side by side as follows.
I want the Add button to only have a width based on the content. And the text view shall take up the rest of the space. I have the following auto layout constraints.
private func setupLayout() {
newDeviceIdTextField.topAnchor.constraint(equalTo: deviceIdLabel.bottomAnchor, constant: 12).isActive = true
newDeviceIdTextField.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 12).isActive = true
newDeviceIdButton.topAnchor.constraint(equalTo: deviceIdLabel.bottomAnchor, constant: 12).isActive = true
newDeviceIdButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -12).isActive = true
newDeviceIdButton.leadingAnchor.constraint(equalTo: newDeviceIdTextField.trailingAnchor, constant: 0).isActive = true
}
In this article there is a section which I believe exactly solves my problem. But I just don't understand how.
What am I missing here?

A button automatically sizes its width to fit its content, and both a text field and a button have an automatic height. So what you want to do is trivial:
Pin the left of the text field where you want it.
Pin the right of the button where you want it.
Pin the tops of both where you want them.
Pin the right of the text field to the left of the button and set that constant to a small number such as 8.

You can do this without writing code, from storyboard. What i do for this kind of UI is,
Pin the left of the text field where you want it.
Pin the right of the button where you want it.
Pin the tops of both where you want them.
Pin the right of the text field to the left of the button
It's look like in image below
Now Select button > Size Inspector > In Content hugging Priority
Change Horizontal to 750(high) and you done :)
Result look like in image below

Related

UIKit: Constraints with respecting NavBar and ignoring safe area at the bottom

I'm following by one of the video of Paul Hudson and trying to recreate detail screen with full screen image. By following the video I set up constraints to Reset to suggested contains but I have different values compering to video. I tried to play around with settings but can't get the expected result...
Constraints:
Image View.top = topMargin - 44
Image View.centerX = centerX
Image View.centerY = centerY
Image View.leading = Safe Area.leading
Result:
Expected:
Question: How to set up constraints to respect NavigationBar and took all other place in the screen, like in expected image?
Assuming your VC is embedded in a navigation controller, you basically want to constraint the left, right and bottom of the image view to be equal to its superview, and the top of the image view to the top layout guide:
You should select the image view, and add the constraints using this pop up:
Click on all four of the thingys I circled. If the first or second items of the constraints added are incorrect, change them by selecting the constraint and using the drop down here:
Alternatively, just add them with code:
imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
imageView.leftAnchor.constraint(equalTo: view.leftAnchor),
imageView.rightAnchor.constraint(equalTo: view.rightAnchor),
imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
Based on answer from Sweeper created constraints in Storyboard:
Image View.leading = leading
Image View.top = Safe Area.top
trailing = Image View.trailing
bottom = Image View.bottom

How can I tell if an iPhone's home indicator is present or not in xcode? [duplicate]

This question already has answers here:
How to detect if the device (iphone) has physical home button?
(2 answers)
Closed 9 months ago.
I have placed a button at the bottom of the safe area.
On iPhone X and later devices, it is placed well above a certain margin, but in the case of an iPhone with a home button, it is attached to the bottom.
So, I would like to set a separate constraint only on iPhones with a home button to leave a certain margin.
iPhoneSE
iPhone 13 Pro
You don't need to detect the home button... in fact, that's probably not what you want to do anyway.
Another approach is to use two bottom constraints, with different priorities.
You can constrain the bottom of the button to the bottom of the safe area, and give that constraint a less-than-required priority.
You can then apply another constraint, this time at a minimum distance from the bottom of the view.
Here's an example:
class BottomPaddingViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let safeAreaView = UIView()
safeAreaView.backgroundColor = .red
safeAreaView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(safeAreaView)
let btn = UIButton()
btn.backgroundColor = .systemBlue
btn.setTitle("Button", for: [])
btn.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(btn)
let g = view.safeAreaLayoutGuide
// bottom constraint for the button
// to the safe area bottom
// with less-than-required priority
let bConstraint = btn.bottomAnchor.constraint(equalTo: g.bottomAnchor)
bConstraint.priority = .required - 1
NSLayoutConstraint.activate([
// constrain the red view to the safe area bottom
safeAreaView.bottomAnchor.constraint(equalTo: g.bottomAnchor),
safeAreaView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
safeAreaView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
safeAreaView.heightAnchor.constraint(equalToConstant: 40.0),
// constrain button 200-pts wide, centered horizontally
btn.widthAnchor.constraint(equalToConstant: 200.0),
btn.heightAnchor.constraint(equalToConstant: 40.0),
btn.centerXAnchor.constraint(equalTo: g.centerXAnchor),
// and bottom AT LEAST 20-points from the bottom of the VIEW
btn.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor, constant: -20.0),
// activate the button's safe area bottom constraint
bConstraint,
])
}
}
When running on a phone without a physical button (iPhone 12, for example) it looks like this:
we see that both the blue button and the red view are bottom-constrained to the safe area.
When running on a phone with a physical button (iPhone 8, for example) it looks like this:
the red view is still constrained to the safe area, but the blue button keeps its minimum distance from the view bottom.

How can I place an activity indictor in a button at a certain distance from the text in the button?

I've got a button which when clicked an activity indictor appears within the button, the indicator should be just infront of the button's text.
I'd tried adding this constraint but its not having any effect. Is this constraint incorrect, what should it be?
_ = continueButton.titleLabel?.leadingAnchor.constraint(equalTo: activityIndicator.trailingAnchor)
There is an existing constraint in the storyboard to center horizontally the activity indicator in the button.
Then your anchors should look something like this:
NSLayoutConstraint.activate(
self.activityIndicator.trailingAnchor.constraint(equalTo: self.titleLabel.leadingAnchor, constant: -5)
self.activityIndicator.topAnchor.constraint(equalTo: self.titleLabel.topAnchor)
])

Align an Icon to the top left of multiline UILabel

On the top left on a UILabel I want to align an Icon. This works file but if the Label has multiple lines the UIImage is aligned in the middle of the UILabel. There are option on interface builder such as first base line, but what I need is something like first line center Y. Is there something similar?
Actually there is a way of doing this! If you use AutoLayout this can be done with the following snippet:
// Aligns the icon to the center of a capital letter in the first line
let offset = label.font.capHeight / 2.0
// Aligns the icon to the center of the whole line, which is different
// than above. Especially with big fonts this makes a visible difference.
let offset = (label.font.ascender + label.font.descender) / 2.0
let constraints: [NSLayoutConstraint] = [
imageView.centerYAnchor.constraint(equalTo: label.firstBaselineAnchor, constant: -offset),
imageView.trailingAnchor.constraint(equalTo: label.leadingAnchor, constant: -10)
]
NSLayoutConstraint.activate(constraints)
The first constraint will display your icon at the Y center of the first line of your label. The second one puts your icon left of the label and creates a 10pt space between them.
Just put constraints as shown in the above image.
Hint: I made label's lines property value to 5 which supports upto 5 lines without any compromise.

How to make a constraint use the view with highest height from an array of views

Let's assume I have 4 views, 3 in a row and 1 in another row. The ones at the first row have dynamic height and we have no idea how tall they are.
I want to achieve the result from this image:
Basically I want to set View 4's top to bottom of highest view in first row. How can I achieve this?
Use greaterThanOrEqualTo:
view4.topAnchor.constraint(greaterThanOrEqualTo: view1.bottomAnchor, constant: 10).isActive = true
view4.topAnchor.constraint(greaterThanOrEqualTo: view2.bottomAnchor, constant: 10).isActive = true
view4.topAnchor.constraint(greaterThanOrEqualTo: view3.bottomAnchor, constant: 10).isActive = true
Put View1, View2 and View3 inside UIStackView (or regular UIView), and then add constraint between bottom of this new view and top of View4

Resources