Button height & programmical setTitle & Autolayout - ios

I use autolayout.
On a screen I have one button + one imageview.
Between this element I set vertical space = 10
| button |
|
10
|
| image |
If I setTitle of button with long text button overlap on image.
How to fix this problem?
EDIT:
Left image as it look now - right as I want that it to be:
This is my constraints:
This is my code:
btnFullLic2.setTitle(getLoc("FULL_VER_DESC"), forState: UIControlState.Normal)
btnFullLic2.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
btnFullLic2.titleLabel?.numberOfLines = 0
btnFullLic2.titleLabel?.clipsToBounds = true

You have to either give maximum height to button or minimum height to image or both depending on your requirement. Adding maximum height constraint to button, will keep the button height from not going beyond that value. While giving minimum height to image, it will have minimum height and overlap the button if it increases.
Hope you understood the concept and get desired result..

Related

What causes horizontal padding around title of UIButton?

I programmatically created two UIButtons and constrained them to 2 points apart (horizontally). I see extra space, so I clicked the "Debug View Hierachy" button in Xcode, and here is what I see:
What is causing the extra space around the "abc" title? I looked at a few suspect properties of the button and they are all zero. (contentEdgeInsets, titleEdgeInsets)
I haven't done anything to the buttons other than:
let b = UIButton(type: .system)
b.translatesAutoresizingMaskIntoConstraints = false
b.setTitle("...", for: .normal)
The constraints look like:
b1.centerXAnchor.constraint(equalTo: outer.centerXAnchor)
b2.leftAnchor.constraint(equalTo: b1.rightAnchor, constant: 2)
b2.firstBaselineAnchor.constraint(equalTo: b1.firstBaselineAnchor, constant: 0)
UIButton has an intrinsic minimum width of 30-pts.
So, if the title text is shorter than 30-pts, the button's title label will be centered horizontally in the button's 30-pt frame.
You can explicitly set the width to less than 30, but then you'll have to take some other steps to get your button to auto-size with a longer title.

How can I format text in Swift to the bottom?

I am making an app where I need text to display directly above a UIImage. When the text is too wide to fit, I need it to display on 2 rows of text, with the bottom one being at the same position vertically as if it only had one row. If the text cannot fit in two rows, I want it to get smaller so that it will just fit in the two rows. Below is an image showing what I mean.
Image
Label constraints : top to superview , leading & trailing & bottom to imageView ,,, with .lines = 2 , textAlignment = .center
ImageView constraints : centerX , width , height

Label doesn't show all the text inside scrollView

I want the DecriptionLabel (the Lorem Ipsum one) to have all the text inside it visible. As you can see, it is getting trimmed.
The two buttons should be under everything else, but in the case where DescriptionLabel contains a small text, the buttons should stick to the bottom of the view.
This is why I chose a >= 20 distance between the buttons and DescriptionLabel if it makes any sense.
How can I solve the trimming of the text?
Thanks.
I was originally answering How to make button stick to bottom of scroll view if the content isn't large enough? but since it is marked as duplicate of this one I am posting my answer here. Please try to set your constraints the following way: https://imageshack.com/a/img923/6671/Txzu98.png
The trick is that you set Button.Bottom Equal To ContainerView.Bottom with lower priority (I use 750) than Button.Top Greater Than Or Equal To Label.Bottom (Here I use default 1000)
The Label has to have number of lines set to 0. The height of the button should be set by height constraint (in this case is 50). The Container View Height constraint should be with low priority (in this case 250)
You should run the code to see actual result on device or simulator. Storyboard shows it a bit differently. For the current question:
https://imageshack.com/a/img923/7276/tQeT0h.png The basic idea is the same. Button Down has the same constraints as Button from above answer without Button.Top Greater Than Or Equal To Label.Bottom. There should be fixed vertical constraint between Button Up and Button Down. I am setting Button Up with fixed Height and setting trailing and leading constraint equal to trailing and leading of Button Down. The constraint Button.Top Greater Than Or Equal To Label.Bottom is now Button Up.Top Greater Than Or Equal To Label.Bottom
Have you set numberOfLines for label to 0 (that means autosize the label according to its text length)?
You should add the following constraints:
(following in sudo code)
// Constraints for ScrollView
scrollView.top = ViewController.view.top
scrollView.leading = ViewController.view.leading
scrollView.trailing = ViewController.view.trailing
scrollView.bottom = ViewController.view.bottom
// Constraints for View
view.top = scrollView.top
view.leading = scrollView.leading
view.trailing = scrollView.trailing
view.bottom = scrollView.bottom
// Width of view
view.width = ViewController.view.width
Now you just need to make sure you have layout constraints for each child of the 'view' and it's height will be correct and display the full size of the textview.
Add the following constraint:
scrollview.contentview.height >= safearea.height
This may show an error in interface builder but works in my tests:
To remove the design time error you could set a design time intrinsic content size for the scrollview's contentview (in my case I used the safe area's height of 554):
Another option (without placeholder values in IB) is to create the following constraint...
scrollview.contentview.height = safearea.height
... and change its priority to a value lower than the label's vertical content compression resistancy.

Swift 4 - Editing label frame.size.height with negative number

So I have a label that I've made in Xcode's storyboard which I want to later edit in my code. I want it to simulate something like a vertical bar so I am editing its height by doing:
answerE.frame.size.height = -200
The problem comes from the negative number, I want the label to "grow" up so the height has to be negative from its original position... I have the line in code in a simple action on button press, but each time the line is executed the label moves "up" and eventually after 3-4 clicks is out of the screen.
I just want to edit its height, what is the correct way and what am I doing wrong?
My exact line in code is:
label.frame.size.height = -CGFloat(Double(x)/Double(y) * (200))
If you have added the label in storyboard, why not you use constraints to get the result.
Add leading, trailing , bottom and fixed height constraint and connect IBOutlet to height constraint. Change the constant value of height constraint at the event which you want to perform.
If I'm right, you want the label to gain height, keeping the same bottom edge, but the top edge moving up.
In order to do this, you want to change the frame.origin.y as you change the frame.size.height at the same amount, as its placement (and so top edge) is determined by its origin. So maybe make it zero height, place it where you want it in storyboard, and then when you want it to 'grow' by x:
label.frame.size.height = label.frame.height + x
label.frame.origin.y = label.frame.origin.y - x

Two labels alignment and its constraints

I have 2 labels: the description label (w/ red background) and the results label (gray text)
How do i set constraints for this example in order to have the results label with the size of its content and the description label until the results leadingAnchor? (like i have in the second row)
Objective C
[self.customTextLabel.trailingAnchor constraintLessThanOrEqualToAnchor:self.counterLabel.leadingAnchor].active = YES;
[self.counterLabel.widthAnchor constraintGreaterThanOrEqualToConstant:0].active = YES;
swift
titleLabel.trailingAnchor.constraint(lessThanOrEqualTo: counterLabel.leadingAnchor).isActive = true
counterLabel.widthAnchor.constraint(greaterThanOrEqualToConstant: 0).isActive = true
I have a solution that i think it's ugly.
self.counterLabelWidthConstraint = [self.counterLabel.widthAnchor constraintEqualToConstant:0];
self.counterLabelWidthConstraint.active = YES;
And then after i set the text:
self.counterLabelWidthConstraint.constant = [self.counterLabel sizeThatFits:CGSizeMake(CGFLOAT_MAX, self.counterLabel.height)].width;
The way to do this with auto layout is by using the contentCompressionResistancePriority of the 2 labels. Set the pririty to NSLayoutPriorityRequired for the second label and something lower like NSLayoutPriorityDefaultLow for the first label. Then, as long as the 2 labels have proper constraints anchoring them to their superview and each other, the first label should compress while the second label should not.
You just need to increase the horizontal compression resistance of the right/gray label to be higher than that of the left/red label. This tells the visual layout that, in the event that there is not enough space for both labels, the one on the left will be compressed before shrinking the label on the right. 750 is the default for all views, so just increase the right/gray label's horizontal compression resistance to 751 and you should be good to go.
Swift 5 programatically:
<#label#>.setContentCompressionResistancePriority(.required, for: .horizontal)
Labels with this property will not compress horizontally.
You can set constraints for in storyboard itself. Select Label 1 (red back ground) and label's superview set widths are equal constraint. Select Label 1 and double tap on its width constraint, from the resultant window, you could see Lable 1 width equal to superview with value constant as '1'. change '1' to 0.7 or whichever the percentage you want.

Resources