Unexpected behavior for adjustsFontSizeToFitWidth - ios

I'm wondering why my UILabel isn't resizing the font correctly when the numberOfLines is set to 1. I have a playground set up with the code below:
import UIKit
import PlaygroundSupport
let labelFrame = CGRect(x: 0, y: 0, width: 100, height: 100)
let label = UILabel(frame: labelFrame)
label.backgroundColor = .lightGray
label.text = "Something that's pretty long"
label.baselineAdjustment = .alignCenters
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 1
label.minimumScaleFactor = 0.1
let frame = CGRect(x: 0, y: 0, width: 300, height: 300)
let view = UIView(frame: frame)
view.backgroundColor = .white
view.addSubview(label)
PlaygroundPage.current.liveView = view
And this is the result
However, when I change the numberOfLines to 2 the font shrinks just like I'd expect:
import UIKit
import PlaygroundSupport
let labelFrame = CGRect(x: 0, y: 0, width: 100, height: 100)
let label = UILabel(frame: labelFrame)
label.backgroundColor = .lightGray
label.text = "Something that's pretty long"
label.baselineAdjustment = .alignCenters
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 2 // <<<<<< this is the only change
label.minimumScaleFactor = 0.1
let frame = CGRect(x: 0, y: 0, width: 300, height: 300)
let view = UIView(frame: frame)
view.backgroundColor = .white
view.addSubview(label)
PlaygroundPage.current.liveView = view
And here's the result:
What's going on here? Is this a bug or am I doing something wrong?

Hmmmm it looks like this is just a bug in Playgrounds. If I add this line
label.lineBreakMode = .byTruncatingMiddle
everything works as expected. Actually, ANY of these work:
label.lineBreakMode = .byCharWrapping
label.lineBreakMode = .byClipping
label.lineBreakMode = .byTruncatingHead
label.lineBreakMode = .byTruncatingMiddle
label.lineBreakMode = .byWordWrapping
the one that doesn't work (and is also the default) is
label.lineBreakMode = .byTruncatingTail
When I tried this in a real simulator everything looked good, so I assume I just ran into a Playgrounds bug.

Related

UINavigationItem TitleView Cutting Off When Using UIView

I am trying to display a multi-line titleView in my app. Here is my code to set the titleView.
self.titleView = TitleView(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: self.tableView.frame.width, height: 80)), title: "NEWS", subtitle: Date.dateAsStringForNavBarSubTitle())
self.titleView.backgroundColor = UIColor.red
self.navigationItem.titleView = self.titleView
The part of the implementation of TitleView is shown below:
private func setupUI() {
let label = UILabel(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: self.frame.width, height: self.frame.height)))
label.numberOfLines = 2
label.text = "\(self.title)\n\(self.subtitle)"
self.addSubview(label)
}
The label comes out to be outside the parent view.
Should I just use a UILabel instead of putting it in UIView?
I can see that you are adding label subview into title view. Instead, you can try this in your viewcontroller's viewDidLoad() method.
For Swift 4
let label = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: 44.0))
label.backgroundColor = .red
label.numberOfLines = 2
label.textAlignment = .left
label.text = "\(self.title)\n\(self.subtitle)"
self.navigationItem.titleView = label
For more information please refer this link UINavigationBar multi-line title

how to set different texts to labels with tags in a scrollview in swift 3?

homeScrollView.frame = CGRect(x: 0, y: 0, width: screenWidth, height:
homeView.bounds.size.height)
for i in 0 ..< 3 {
scrollBtnLbl1 = UILabel()
scrollBtnLbl2 = UILabel()
scrollBtnLbl3 = UILabel()
scrollViewStartHeight = scrollViewStartHeight+50
scrollBtnLbl1.frame = CGRect(x: (screenWidth-450)*1/4, y: scrollViewStartHeight+180, width: 150, height: 30)
scrollBtnLbl1.text = "about worldcup"
scrollBtnLbl1.font = UIFont(name: "Metropolis-Regular", size: 15)
scrollBtnLbl1.textColor = UIColor.black
scrollBtnLbl1.textAlignment = .center
scrollBtnLbl1.tag = i
homeScrollView.addSubview(scrollBtnLbl1)
scrollBtnLbl2.frame = CGRect(x: (screenWidth-450)*2/4 + 150, y: scrollViewStartHeight+180, width: 150, height: 30)
scrollBtnLbl2.text = "top goals"
scrollBtnLbl2.font = UIFont(name: "Metropolis-Regular", size: 15)
scrollBtnLbl2.textColor = UIColor.black
scrollBtnLbl2.textAlignment = .center
scrollBtnLbl2.tag = i
homeScrollView.addSubview(scrollBtnLbl2)
scrollBtnLbl3.frame = CGRect(x: (screenWidth-450)*3/4 + 300, y: scrollViewStartHeight+180, width: 150, height: 30)
scrollBtnLbl3.text = "top goals"
scrollBtnLbl3.font = UIFont(name: "Metropolis-Regular", size: 15)
scrollBtnLbl3.textColor = UIColor.black
scrollBtnLbl3.textAlignment = .center
scrollBtnLbl3.tag = i
homeScrollView.addSubview(scrollBtnLbl3)
scrollViewStartHeight = scrollViewStartHeight+300
}
I have 9 labels in scrollview which is homescrollview and I want to give different texts to each of them. I have assigned tags to each of it, but I don't know how to access those labels with tags. any help is appreciated, thanks in advance.
You can access them by viewWithTag method:
if let lbl = self.view.viewWithTag(1 /*your UILabel tag*/) as? UILabel {
lbl.text = "some text"
}

Auto-resized navigationBar title misplaced

I have a UINavigationBar with a title of variable length. To make sure the title fits without being truncated I've implemented the following code in my viewDidLoad():
let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
titleLabel.text = "\(petsName)'s Day"
titleLabel.font = UIFont.systemFont(ofSize: 30)
titleLabel.backgroundColor = UIColor.clear
titleLabel.textColor = UIColor.white
titleLabel.adjustsFontSizeToFitWidth = true
titleLabel.minimumScaleFactor = 0.5
self.navBar.topItem?.titleView = titleLabel
However, because I have a bar button item, the title is being moved over to the left:
Is there any way to implement the code above but keep the text center aligned within the navigation bar?
Please help me to resolve this issue
Try this.. may be worked
var view = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 40))
var label = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 40))
label.text = "Joys Day"
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 30)
view.addSubview(label)
navigationItem?.titleView = view
Change titleLabel width to device width and align it to center. Try this:
let deviceWidth = UIScreen.main.bounds.size.width
let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: deviceWidth, height: 40))
titleLabel.text = "My Test Title"
titleLabel.font = UIFont.systemFont(ofSize: 20)
titleLabel.backgroundColor = UIColor.clear
titleLabel.textColor = UIColor.white
titleLabel.adjustsFontSizeToFitWidth = true
titleLabel.minimumScaleFactor = 0.5
titleLabel.textAlignment = .center
self.navigationItem.titleView = titleLabel
Output:

Place label above each element in scrollview?

I'm populating my scrollview in a for loop and trying to place a UILabel on top of each inserted element. However, the label won't center horizontally for some reason even though I'm setting its centerXAnchor to be equal to each element's centerXAnchor. Here's a picture with the label and element's borders shown:
As seen, the label I'm inserting isn't being centered horizontally with each element in the scrollview for some reason. Here's my for loop where I populate the scrollview:
for i in 0..<petsDict.count {
let imageView = UIImageView()
imageView.image = petsDict[i]
imageView.contentMode = .scaleAspectFit
let xPos = self.view.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPos - CGFloat(20*i), y: 0, width: self.mainScrollView.frame.width, height: self.mainScrollView.frame.height)
let label = UILabel(frame: CGRect(x: 0, y: -20, width: 200, height: 40))
label.text = "Joy"
label.textAlignment = .center
imageView.addSubview(label)
label.font = UIFont(name: "SFUIText-Regular", size: 20)!
label.sizeToFit()
mainScrollView.contentSize.width = mainScrollView.frame.width * CGFloat(i + 1)
mainScrollView.addSubview(imageView)
label.centerXAnchor.constraint(equalTo: imageView.centerXAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: imageView.topAnchor).isActive = true
}
Can anybody help me understand why my x centering isn't working properly?
Try to remove label.sizeToFit(), this function resizes your labels.
for i in 0..<petsDict.count {
let imageView = UIImageView()
imageView.image = petsDict[i]
imageView.contentMode = .scaleAspectFit
let xPos = self.view.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPos - CGFloat(20*i), y: 0, width: self.mainScrollView.frame.width, height: self.mainScrollView.frame.height)
let label = UILabel(frame: CGRect(x: 0, y: -20, width: self.mainScrollView.frame.width, height: 20))
label.text = "Joy"
label.textAlignment = .center
imageView.addSubview(label)
label.font = UIFont(name: "SFUIText-Regular", size: 20)!
mainScrollView.contentSize.width = mainScrollView.frame.width * CGFloat(i + 1)
mainScrollView.addSubview(imageView)
label.centerXAnchor.constraint(equalTo: imageView.centerXAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: imageView.topAnchor).isActive = true
}
Try this code
Give width to label same as your imageview width and remove sizeToFit and anchor. You just need to add then textAlignment which you have already added.

iOS Badge like UILabel glitch

please help me to make a simple badge like UILabel.
My code is:
let badgeLabel = UILabel(frame: CGRectMake(0, 0, 25, 25))
badgeLabel.backgroundColor = UIColor.clearColor()
badgeLabel.layer.backgroundColor = UIColor.redColor().CGColor
badgeLabel.layer.cornerRadius = 25/2
badgeLabel.layer.borderWidth = 3.0
badgeLabel.layer.borderColor = UIColor.whiteColor().CGColor
And in result I have a UILabel with tiny red stroke on white border:
Try this.
let badgeLabel = UILabel(frame: CGRectMake(0, 0, 25, 25))
badgeLabel.backgroundColor = UIColor.redColor()
badgeLabel.layer.backgroundColor = UIColor.clearColor().CGColor
badgeLabel.layer.cornerRadius = 25/2
badgeLabel.layer.borderWidth = 3.0
badgeLabel.layer.borderColor = UIColor.whiteColor().CGColor
Hey Check this latest code, sure it will work.
let roundRing = UILabel(frame: badgeLabel.frame)
roundRing.backgroundColor = UIColor.clearColor()
roundRing.layer.backgroundColor = UIColor.whiteColor().CGColor
roundRing.layer.cornerRadius = 25/2
roundRing.layer.borderWidth = 3.0
roundRing.layer.borderColor = UIColor.whiteColor().CGColor
self.view .addSubview(roundRing)
let innerRegion = UILabel(frame: CGRectMake(3, 3, 19, 19))
innerRegion.backgroundColor = UIColor.clearColor()
innerRegion.layer.backgroundColor = UIColor.redColor().CGColor
innerRegion.layer.cornerRadius = 19/2
innerRegion.text="2"
innerRegion.font=UIFont(name: "MarkerFelt-Thin", size: 10)!
innerRegion.textAlignment=NSTextAlignment.Center
roundRing.addSubview(innerRegion)
You are missing masksToBounds
for swift 3:
let badgeLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
badgeLabel.backgroundColor = .red
badgeLabel.layer.cornerRadius = 25/2
badgeLabel.layer.masksToBounds = true
badgeLabel.layer.borderWidth = 3.0
badgeLabel.layer.borderColor = .white

Resources