I'm a beginner in Swift and Xcode. As my very first project without tutorials I try to do basic Calculator app. My goal is to make it look like original calculator app on iOS 9. Everything works, but I don't know how to fit all numbers on the screen. In Apple app, if there are more numbers, they're getting smaller. How to do that?
For UITextField:
You have to set the adjustFontSizeToFitWidth property to yes and provide a suitable small value for the minimumFontSize.
Both together will cause the UITextField to reduce its font size to fit the string in its bounds.
let textfield = UITextField()
textfield.adjustsFontSizeToFitWidth = true
textfield.minimumFontSize = 5
// ... more
For UILabel:
You have to set the adjustsFontSizeToFitWidth property to yes and provide a suitable small value for the minimumScaleFactor.
Both together will cause the UILabel to reduce its font size to fit the string in its bounds.
let label = UILabel()
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.05
// ... more
Related
I have a single line UILabel. It has width = screen width and the content now is (the content of UILabel can change)
You have 30 seconds to make an impression during an interview
Currently, my UILabel is truncated tail and the word "duration" is not complete
self.nameLabel.lineBreakMode = NSLineBreakByTruncatingTail;
What I want is I want my UILabel still truncating tail and only display complete word.
Like the image below
Any help or suggestion would be great appreciated.
You can do something like this:
let labelWidth = CGRectGetWidth(label.bounds)
let str = "You will have 30 seconds till you give us a good impression" as NSString
let words = str.componentsSeparatedByString(" ")
var newStr = "" as NSString
for word in words{
let statement = "\(newStr) \(word) ..." as NSString
let size = statement.sizeWithAttributes([NSFontAttributeName:label.font])
if size.width < labelWidth {
newStr = "\(newStr) \(word)"
}
else{
break
}
}
newStr = newStr.stringByAppendingString(" ...")
self.label.text = newStr as String
Idea is: we split words and try check the width while appending from the beginning + the string "..." till we found the a word that will exceed the size, in the case we stop and use this new string
Ideally this is not possible,with default UILabel, when you set lineBreakMode to TruncatingTail, depending on the space required by the letter/word the OS will truncate it, one solution to fix the issue you can use following properties depending on your match.
Minimum Font Scale -- Use this property to specify the smallest multiplier for the current font size that yields an acceptable font size to use when displaying the label’s text. If you specify a value of 0 for this property, the current font size is used as the smallest font size.
Minimum Font Size -- When drawing text that might not fit within the bounding rectangle of the label, you can use this property to prevent the receiver from reducing the font size to the point where it is no longer legible.
i am not sure but try it:
nameLabel.adjustsFontSizeToFitWidth = NO;
nameLabel.lineBreakMode = NSLineBreakByWordWrapping;
OR
If you are using storyboard follow these steps i tried this and it working fine
Open Attribute Inspector
Change Line Breaks to Truncate Tail then
Change AutoShrink to Minimum Font Size
here are my screenshots of label after and before applying these properties
new output
I try to setup a custom button with UIImage and UILabel
After setting up constraints, I started testing this button and noticed strange behavior
UILabel in UIButton code:
private var title: UILabel = {
var label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 14)
label.numberOfLines = 0
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.5
return label
}()
When I set title for example "Hfpdktxtybz", UILabel works amazing!
One word takes one line:
But if I try set title for example "Развлечения", UILabel truncates the word.
One word is split into two lines:
Why for English language label work is correctly, but for Russian language truncates the word? How to fix it?
The number of characters is the same
The problem is, as said in the comments, that characters don't necessarily have the same width.
lllll
AAAAA
aaaaa
The above example clearly shows characters do not have the same width although they have same character count.
So Autolayout calculates the UILabel real width and it has only one option in order to satisfy your constraints. That is to split it into 2 lines.
If you don't want this to happen consider changing UILabel priority numberOfLines.
if you use storyboard
if you use swift programmatically.
label.numberOfLines = 2
Below is the code in Swift I used for a 2 line UILabel with adjustsFontSizeToFitWidth set to true, working properly for left-to-right text. I have used EasyPeasy library for setting layout constraints.
let contactLabel = UILabel()
contactLabel.text = "Tell us how we can contact you".localized()
contactView.addSubview(contactLabel)
contactLabel.easy.layout([Leading(), Trailing(), Top(20), Height(60)])
contactLabel.numberOfLines = 2
contactLabel.lineBreakMode = .byTruncatingHead
contactLabel.adjustsFontSizeToFitWidth = true
When I changed the language to Arabic, the text will be broken to two lines properly but shown in LTR mode instead of RTL. How should manage a multiline label to show Arabic text?
I also checked this behavior on iOS 11 and it is working, maybe there is a trick to it in iOS 12.
Don't set a specific height because of that is not expanding to your amount of text.
Steps 1 - Set top, leading, trailing and height constraint and change height relation to Greater Than or Equal to
Step 2 - label.numberOfLines = 0
Step 3 - label.sizeToFit()
step 4 - label.lineBreakMode = .byTruncatingTail
Although setting the label alignment to "natural" works in most cases, iOS sometimes gets it wrong. If you're out of ideas, you can always set it manually in the code based on the current layout direction of the application.
if UIApplication.shared.userInterfaceLayoutDirection == .leftToRight {
resultLabel.textAlignment = .left
} else {
resultLabel.textAlignment = .right
}
I have a UITextField that will display floating point values between 0 and 1.0 with 3 digits after the decimal point. So the widest text it will show is something like "0.000". I'd like to set the auto layout width constraint so that the text field always has just enough room to display this value.
The code below is close, but does not work.
let biggestString = "0.000"
let textAttrs = [NSAttributedStringKey.font: myField.font]
let size = (biggestString as NSString).size(withAttributes: textAttrs)
myField.widthAnchor.constraint(equalToConstant: size.width).isActive = true
It ends up displaying "1.0..." I'm guessing this is because a UITextField has some kind of padding around the text, so so I need to set the width to be the string width + the padding. But, I don't see a property from which I can read this padding amount. Is there a way to get it?
Try searching for the 'intrinsicContentSize'. According to the documentation this is what has to be set to indicate to the auto-layout how big the content is.
There was also a more elaborate discussion on how this can actually if the layout settings do not allow the resizing to work, see other question here:
How to increase width of textfield according to typed text?
I have a single line UILabel. It has width = screen width and the content now is (the content of UILabel can change)
You have 30 seconds to make an impression during an interview
Currently, my UILabel is truncated tail and the word "duration" is not complete
self.nameLabel.lineBreakMode = NSLineBreakByTruncatingTail;
What I want is I want my UILabel still truncating tail and only display complete word.
Like the image below
Any help or suggestion would be great appreciated.
You can do something like this:
let labelWidth = CGRectGetWidth(label.bounds)
let str = "You will have 30 seconds till you give us a good impression" as NSString
let words = str.componentsSeparatedByString(" ")
var newStr = "" as NSString
for word in words{
let statement = "\(newStr) \(word) ..." as NSString
let size = statement.sizeWithAttributes([NSFontAttributeName:label.font])
if size.width < labelWidth {
newStr = "\(newStr) \(word)"
}
else{
break
}
}
newStr = newStr.stringByAppendingString(" ...")
self.label.text = newStr as String
Idea is: we split words and try check the width while appending from the beginning + the string "..." till we found the a word that will exceed the size, in the case we stop and use this new string
Ideally this is not possible,with default UILabel, when you set lineBreakMode to TruncatingTail, depending on the space required by the letter/word the OS will truncate it, one solution to fix the issue you can use following properties depending on your match.
Minimum Font Scale -- Use this property to specify the smallest multiplier for the current font size that yields an acceptable font size to use when displaying the label’s text. If you specify a value of 0 for this property, the current font size is used as the smallest font size.
Minimum Font Size -- When drawing text that might not fit within the bounding rectangle of the label, you can use this property to prevent the receiver from reducing the font size to the point where it is no longer legible.
i am not sure but try it:
nameLabel.adjustsFontSizeToFitWidth = NO;
nameLabel.lineBreakMode = NSLineBreakByWordWrapping;
OR
If you are using storyboard follow these steps i tried this and it working fine
Open Attribute Inspector
Change Line Breaks to Truncate Tail then
Change AutoShrink to Minimum Font Size
here are my screenshots of label after and before applying these properties
new output