NSLabel Autoshrink with top constraints - ios

I try to figure out autoshrink option in UILabel with regarding top constraint.
I have UIView and three labels. One of them has autoshrink option on. It has constraint to be centered, and has Trailing and Top constraint which should shrink label when changing size of UIView. If I make UIVIew thinner, font size is decreased, but if I change height of UIView font is not changed.
Constraints on UILabels :
Align Center X to Superview
Align Center Y to Superview
Trailing Space to Superview >= 50
Top Space to Superview >= 40
Align Center X to label2
Top Space to label1 equals :15
Bottom space to label2 equals :3
Label 1 constraints :
Align Center x to superview
Trailing Space to superview >=10
Leading Space to superview >=10
Bottom Space to Shrink Label equal 15
Label 2 constraint :
Align Center X to Shrink label
Top Space to Shrink label equals 3
How to change this?
What I want is, on last image that label will be nice autoshrink. So if I change width or height of the UIView label should shrink.

plz select your Shrink label set
Number of lines is 0
Line Breaks: Clip
Autoshrink: Minimum Font Scale 0.25

I hope below code will help you in some way,
extension Double {
/// Returns propotional width according to device width
var propotional: CGFloat {
if UIDevice.current.userInterfaceIdiom == .pad {
return CGFloat(414.0) / CGFloat(375.0) * CGFloat(self)
}
return CGFloat(Screen.width) / CGFloat(375.0) * CGFloat(self)
}
}
extension UILabel {
/// This property is change font-size of Label's text propotionaly, if assigned `On` from Interface builder
#IBInspectable
var isPropotional: Bool{
get {
return true
}
set {
if newValue == true {
let fontSize = Double((self.font!.pointSize))
self.font = UIFont(name: self.font!.fontName, size: fontSize.propotional)
}
}
}
}
In extension of Double, propotional value is calculated by considering current device set in storyboard as iPhone 6 size.
After adding this code set on from interface builder for Label where you can see isPropotional attribute in attribute inspector tab. Please refer image.

Related

UIButton not render exactly as XIB's contentVerticalAlignment value

I want to button 's top is align to the button's titleLabel's top , so I set the content vertical alignment to top in xib . this is works well in xib , but after build , the titleLabel seems still layout with center vertical alignment . What did I miss?
First, a comment: What you see in Storyboard / Interface Builder:
is not always exactly what UIKit renders in the Simulator
which is not always exactly what UIKit renders on a Device
This is why we test, test, test... on different simulators and devices.
So, what's going on here?
UIKit uses the frame of the button's .titleLabel to determine the button's intrinsic size.
For a default button, with no explicit width or height set, UIKit insets the title label by 6-pts on the Top and Bottom.
Here are 2 buttons - both with no Height constraint. Button 1 is the default Content Alignment of center/center, Button 2 is set to Left/Top. The button title label background is cyan, so we can easily see its frame.
Storyboard / IB:
Runtime:
Debug View Hierarchy (note the label frame vs the button frame):
So, with an 18-pt system font, the title label height is 21.0 ... add 6-pts top and bottom and the button frame height is 33-pts.
It doesn't matter whether you set the Control Alignment to Top / Center / Bottom or Fill ... UIKit still takes the label height and adds 6-pts Top and Bottom "padding."
What to do to get actual Top alignment? Let's look at a couple approaches.
Here are 6 buttons in a stack view:
Button 1 is at the default center/center, with no Height constraint.
Button 2 as we've seen, has Control Alignment Left / Top ... but has no effect on the vertical alignment.
Button 3 is also Left/Top, but let's give it an explicit Height (we'll use 80 to make things obvious). Looks better - but there is still 6-pts of "padding" added to the top of the title label.
Now, you may have seen this at the top of the Size Inspector panel:
This looks promising! Let's set the Title Insets Top to Zero!
Whoops -- it's already Zero?!?!?!?
Same thing with the Content Insets!
Turns out, if the the edge insets are at the default, the padding is added anyway.
We could try setting the Title Inset Top to -6 and, because labels center the text vertically, we'll also have to set the Bottom inset to 6. This works... but we may not want to rely on that value of 6 to be accurate in future iOS versions.
Button 4 - lets try Content Insets -> Bottom: 1 ... and it looks like we're on our way! The label is now top-aligned with the button frame!
So...
Button 5 - remove the Height: 80 constraint so we can use the default button height. D'oh! The button frame height is now title-label-height plus zero-top plus one-bottom...
Button 6 - finally, we'll use Content Insets -> Bottom: 1 with an explicit Height constraint of 33 (the default button height).
So... what if we don't want to set an explicit Height? Perhaps we're going to change the title label's font size later? Or we run into some other issue?
You could use a custom UIButton subclass.
Here's an example, marked as #IBDesignable so we can see its layout in Storyboard / IB:
#IBDesignable
class MyTopLeftAlignedButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
commonInit()
}
func commonInit() {
self.contentVerticalAlignment = .top
self.contentHorizontalAlignment = .left
// if we want to see the title label frame
//titleLabel?.backgroundColor = .cyan
}
override var bounds: CGRect {
didSet {
if let v = titleLabel {
var t = titleEdgeInsets
let h = (bounds.height - v.frame.height) * 0.5
t.top = -h
t.bottom = h
titleEdgeInsets = t
}
}
}
}
Edit - response to comment...
If your goal is to match the "Button 5" style - where the button height matches the title label height - best bet is probably...
Select the button, then in the Size Inspector panel use these settings:
The 0.1 Top and Bottom values will override the default 6-pt Top/Bottom "padding," reducing it to effectively Zero.

How to set auto size text for different screens

My task is to preserve the size and position of the elements inside my cell for different screen resolutions.
I did:
Established constraints for the red and green blocks (UILabels) to
the outer container.
Set the constraint between them equal to 0. It is more priority than the limitation of the red block to the bottom and green to the top.
Set Lines = 0 for these labels.
Set Autoshrink.
As a result, the font size changes on different devices. But there are still a few problems:
How can I remove too large paddings above and below both labels?
How to make them resize evenly?
Now one of the blocks has an advantage over the other, depending on what constraint to make a higher priority. If you make them equal - it also does not work.
(I would like to do everything through Interface Builder)
Screenshot with differing priorities of constraints
My constraints
Paddings and Attributes
You can take advantage of equal height and equal width constraints.
Follow the below steps to make the UILabel spacing same on iPhone 8 and iPhone 4s. This will help you to make it proportional.
1) To achieve this simply select, your label(red), label (green) and the superview (which I think you're its a cell of UICollectionView)
2) We are interested here in keeping the height proportional.
i.e Red Label (80%) and Green Label (20%)
Currently, all heights are equal to superview height i.e height of RedLabel and Greenlabel is equal to 100% of superview.
But the goal is to make it 80% and 20% for red and green label respectively.
So select Red Label height constraint. Here you set the constraint which says's "height of the red label should be 80% of the superviews height".
Similarly for Green Label, set "height of the greeen label such that it's 20% for the superview's height".
Red Label
Green Label
3) Now complete the x and y axis position constraint, which would be straight forward
a) Red Label Leading = Leading edge of superview
b) Red Label Trailing = Trailing edge of superview
c) Red Label Top = Top edge of superview
d) Red Label Bottom = not required (as it has all the required constraint's to justify it's position i.e height = 0.8 * superview and it is top aligned, ex: super view height is 100 , keep this view top aligned with height = 80 )
e) Green Label Leading = Red Label Leading (you have already set this in point "a" no need to set the constraint again for Green label)
f) Green Label Trailing = Red Label Leading (you have already set this in point "b" no need to set the constraint again for Green label)
g) Green label bottom = bottom of superview
h) Green label top = not required (as it has all the required constraint's to justify it's position i.e height = 0.2 * superview and it is bottom aligned, ex: super view height is 100 , keep this view bottom aligned with height = 20 )
This is the final constraint list and the storyboard preview for iPhone 8 and 4s.

fitting only the height of a label

how to fit only the height size of label ...
i have tried this:
servicedes.sizeToFit()
but this will fit both height and width... while i just want to fit the height of it so the text will be at the first line of the label ... my label is a multi lines label ..
this is my label
and this is what i got:
the space by the blue arrow is what i don't want ...
constraints:
how to do this?
Layout constraints aside, you should be able to use .sizeToFit() in a way that it only resizes the label's height by setting the width just before:
label.frame.width = label.frame.width
label.sizeToFit()
This approach won't work when using the constraints you're using right now.
Do the following:
Remove 'Center X' Constraint of the label
Add Trailing constraint(eg. 8) to the label and set relation of Trailing Constraint to 'greater than/equal to'.
Adding Trailing constraint:
Setting Relation:

Which Constraint we need to make dynamic View height in iOS

As I am new to iOS. So forgive me if it is duplicate or very basic question.
I am taking one View. Approx below is the size .
x : 5 y : 5
Width : 590 Height : 100
and I set constraint it
Top to superView 5
Trailing to superView 5
Leading to superView 5
Now I have one Label which have dynamic Text and the Text is too large.
And the Label Constraint is below
Top to superView 5
Trailing to superView 5
Leading to superView 5
and when i set the background color of the View the color is not set. If the Text is to Long. So how to set the Height of the View and also set background so that it looks clear.
Code :
public override void ViewDidLoad()
{
base.ViewDidLoad();
lbl_one.Text = "This is a long label which have long text inside the writing. This is a long label which have long text inside the writing. This is a long label which have long text inside the writing. This is a long label which have long text inside the writing";
lbl_one.LineBreakMode = UILineBreakMode.WordWrap;
lbl_one.Lines = 0;
view_main.BackgroundColor = UIColor.Red;
}
If I give fix Height then it look like this .
Output :
1. Give the below constraints to your view, height is according to your need. here I'm giving 80.
2. Change the height relationship.
3. Add aUILabel in your above UIview, and give below constraints.
--> leading, top, bottom, trailing to uiview and height i.e. 80.
4. set height relationship as you do with UIView.
5. Change the property of UILabel , Lines to zero
6. Now enjoy with your constraints.
EDIT: Add bottom constraint to your view instead of height constraint.
I don't see and bottom constraint added to UIView, so the view height will be 0.
If you have added the height constraint to UIView, there is a probability that UILablel might be overlapping the UIView, so you are not able to see the background color.
Set the UIView height constraint this will solve your problem
You can also add height or bottom constraint to your UIView.

TableviewCell dynamic height - auto layout issues

I need to implement a news feed like instagram but I'm facing some troubles with my constraints.
I have a tableView cell with: imageView, label 1, label 2, view 1 and view 2 in a vertical order like this:
I need to achieve the following conditions:
- my image is square.
- label 1 (the black one) have 5 lines max
- label 2 (the red one) don't have a max number of lines
- view 1 is 30px height
- view 2 is 35px height
My constraints are:
Image:
trailing space to superview
leading space to superview
top space to superview
botton space to label 1 with constant=8
height = 320 with priority=999 (during runtime I change this value to view's width)
Content hugging - Vertical = 751, Horizontal=751
Content compression - Vertical = 1000, Horizontal = 751
Label 1:
trailing space to superview with constant=-20 and priority=999
leading space to superview with constant=20
height >=20 with priority= 750
bottom space to label2 with constant=8
Content hugging - Vertical = 1000, Horizontal=752
Content compression - Vertical = 1000, Horizontal = 751
Label 2:
trailing space to superview with constant=-20 and priority=999
leading space to superview with constant=20
height >=20 with priority= 750
bottom space to view1 with constant=8
Content hugging - Vertical = 1000, Horizontal=752
Content compression - Vertical = 1000, Horizontal = 751
View 1:
trailing space to superview
leading space to superview
botton space to view2
height = 30
Content hugging - Vertical = 1000, Horizontal=250
Content compression - Vertical = 1000, Horizontal = 750
View 2:
trailing space to superview
leading space to superview
botton space to superview
height = 35
Content hugging - Vertical = 1000, Horizontal=750
Content compression - Vertical = 1000, Horizontal = 750
During runtime I receive several warning about constraints. It can't satisfy all my constraints.
"<NSLayoutConstraint:0x7fec35712d60 V:[UIView:0x7fec357391e0(30)]>",
"<NSLayoutConstraint:0x7fec3570a8f0 V:[UIView:0x7fec357432a0(35)]>",
"<NSLayoutConstraint:0x7fec350d17b0 V:|-(0)-[UIImageView:0x7fec35711340] (Names: '|':UITableViewCellContentView:0x7fec35744f30 )>",
"<NSLayoutConstraint:0x7fec350bf830 V:[UIImageView:0x7fec35711340]-(8)-[TimelineLabel:0x7fec3570a980'Usura']>",
"<NSLayoutConstraint:0x7fec350bc7e0 V:[TimelineLabel:0x7fec3570a980'Usura']-(8)-[UILabel:0x7fec350ddb40'Produtos: BATOM: MAC, SOM...']>",
"<NSLayoutConstraint:0x7fec35701f20 V:[UILabel:0x7fec350ddb40'Produtos: BATOM: MAC, SOM...']-(8)-[UIView:0x7fec357391e0]>",
"<NSLayoutConstraint:0x7fec350e90c0 V:[UIView:0x7fec357391e0]-(0)-[UIView:0x7fec357432a0]>",
"<NSLayoutConstraint:0x7fec350e9110 UIView:0x7fec357432a0.bottom == UITableViewCellContentView:0x7fec35744f30.bottom>",
"<NSLayoutConstraint:0x7fec357085c0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7fec35744f30(0)]>"
Will attempt to recover by breaking constraint
NSLayoutConstraint:0x7fec3570a8f0 V:[UIView:0x7fec357432a0(35)];
For each cell in my tableView break a different constant.
I tried a lot of solutions but none works.
Help! Please!
The warnings are about unbreakable constraints in a dynamic TableViewCell. But as your layout changes in execution time, you must let your view adapt itself without strict "pixel accuracy" constraints.
You need to set down some of your 1000 priority constraints to 999. This will make Xcode happy about some cases that breaking constraints are needed. In most cases, however, all your constraints will be satisfied. =D

Resources