Stroke text attributes for title in navigation bar are not applied - ios

I can't figure out why the same stroke text attributes look different for navigation bar title and text label. I would like the title to look like the label, please advise:
let myLabel = UILabel(frame: CGRect(x: 50, y: 100, width: 200, height: 30))
let strokeTextAttributes = [NSFontAttributeName: UIFont.init(name:
"Helvetica-Bold", size:20.0),
NSStrokeColorAttributeName : UIColor.black,
NSForegroundColorAttributeName : UIColor.white,
NSStrokeWidthAttributeName : -3.0,
] as [String : Any]
myLabel.attributedText = NSAttributedString(string: "Test", attributes: strokeTextAttributes)
self.navigationController?.navigationBar.titleTextAttributes = strokeTextAttributes
self.title = "Test"
self.view.addSubview(myLabel)

I solved this problem using titleView property of navigationItem like this:
let strokeTextAttributes = [NSFontAttributeName: UIFont.init(name:
"Helvetica-Bold", size:20.0),
NSStrokeColorAttributeName : UIColor.blue,
NSForegroundColorAttributeName : UIColor.white,
NSStrokeWidthAttributeName : -3.0,
] as [String : Any]
let myLabel = UILabel(frame: CGRect(x: 50, y: 100, width: 200, height: 30))
myLabel.attributedText = NSAttributedString(string: "Test", attributes: strokeTextAttributes)
navigationItem.titleView = myLabel

Related

How change height in navigation title?

I need to set the rockwell-bold font in the navigation title, but it is cropped for me. how can I fix this problem or change the height of the navigation titleenter image description here
let customText = NSLocalizedString("your_title", comment: "")
let title:NSMutableAttributedString = NSMutableAttributedString(string: customText, attributes: [.font: UIFont(name: "font_name", size: 20.0) ])
let size = title.size()
let width = size.width
guard let height = navigationController?.navigationBar.frame.size.height else {return}
let titleLabel = UILabel(frame: CGRect(x: 0,y: 0, width: width, height: height))
titleLabel.attributedText = title
titleLabel.numberOfLines = 0
titleLabel.textAlignment = .center
navigationItem.titleView = titleLabel

Shrink size of UINaviationBar large title text

Before iOS 11, to make a custom label, I just did this:
let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 40))
titleLabel.text = self.customTitleText
titleLabel.backgroundColor = .clear
titleLabel.textAlignment = .left
titleLabel.textColor = .white
titleLabel.font = UIFont.boldSystemFont(ofSize: 17)
titleLabel.adjustsFontSizeToFitWidth = true
titleLabel.minimumScaleFactor = 0.25
navigationItem.titleView = titleLabel
Now, the titleView doesn't seem to affect the large title. What can I do to achieve a text shrink in iOS 11?
You can use like this :
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes = [
NSAttributedStringKey.foregroundColor: UIColor.red,
NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 17)
]

NSAttributedString Shadow and Stroke on iOS?

When I use stroke and shadow, I get some sort of double-stroke. How can I fix this?
Playground Code:
import UIKit
var shadow = NSShadow()
shadow.shadowColor = UIColor.black
shadow.shadowOffset = CGSize(width: 0, height: 3)
class CustomLabel: UILabel {
override func drawText(in rect: CGRect) {
let attributes: [String: Any] = [NSStrokeWidthAttributeName: -2.0,
NSStrokeColorAttributeName: UIColor.black,
NSForegroundColorAttributeName: UIColor.white,
NSShadowAttributeName: shadow,
NSFontAttributeName: UIFont(name: "AvenirNext-Bold", size: 50)]
self.attributedText = NSAttributedString(string: self.text ?? "", attributes: attributes)
super.drawText(in: rect)
}
}
let label = CustomLabel(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
label.backgroundColor = UIColor.orange
label.text = "Hello"
Result:
I figured it out. If I apply a shadow to the label's CALayer, and disable the background-color, it works as expected:
import UIKit
class CustomLabel: UILabel {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOffset = CGSize(width: 0, height: 3)
self.layer.shadowOpacity = 1.0
self.layer.shadowRadius = 0.0
}
override func drawText(in rect: CGRect) {
let attributes: [String: Any] = [NSStrokeWidthAttributeName: -2.0,
NSStrokeColorAttributeName: UIColor.black,
NSForegroundColorAttributeName: UIColor.white,
NSFontAttributeName: UIFont(name: "AvenirNext-Bold", size: 50)]
self.attributedText = NSAttributedString(string: self.text ?? "", attributes: attributes)
super.drawText(in: rect)
}
}
let label = CustomLabel(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
label.text = "Hello"

CATextLayer not visible

I have implemented a function to draw the text use of CATextLayer. But after drawing the text is not visible.
Here is my code:
func addText() -> CATextLayer{
let rect:CGRect = CGRect(x: 50, y: 600, width: 120, height: 60)
let myAttributes = [
NSFontAttributeName: UIFont(name: "HelveticaNeue-Thin", size:18)!,
NSForegroundColorAttributeName: UIColor.black.cgColor
] as [String : Any]
let myAttributedString = NSAttributedString(string: "TEST STRING", attributes: myAttributes)
let textLayer = CATextLayer()
textLayer.bounds = rect
textLayer.string = myAttributedString
textLayer.position = CGPoint(x:150,y:400)
textLayer.alignmentMode = kCAAlignmentCenter
textLayer.displayIfNeeded()
return textLayer
}
Does anyone know the problem?

Making NSMutableAttributedString and sizeThatFits work together

I'm having issues making NSMutableAttributedString and sizeThatFits work together. I have a UILabel that must be no wider than a constant self.frame.size.width-usernameX-horizontalMargin. I want the UILabel to be one line if it fits or two lines with a hyphen if it is too long. Currently I am using this code:
let usernameX = profilePhoto.frame.size.width+horizontalMargin
let username = UILabel()
username.adjustsFontSizeToFitWidth = false
username.font = UIFont(name: "SFUIDisplay-Regular", size: 18)
username.numberOfLines = 0
username.translatesAutoresizingMaskIntoConstraints = false
//Set hyphenation
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.hyphenationFactor = 0.2
username.attributedText = NSMutableAttributedString(string: displayName, attributes: [NSParagraphStyleAttributeName: paragraphStyle])
let maxSize = CGSize(width: self.frame.size.width-usernameX-horizontalMargin, height: CGFloat.max)
let requiredSize = username.sizeThatFits(maxSize)
username.frame = CGRect(x: usernameX, y: (self.frame.size.height/2)-21, width: requiredSize.width, height: requiredSize.height)
self.addSubview(username)
Currently the text displays as just one line with a hyphen. The second line isn't showing. Any ideas what I might be doing wrong here? I have tried setting the number of lines to 2, that made no difference. Any pointers would be really appreciated.
Thanks!
You need to include your font also in attributes, else it will take default fond for attributed text. Can you try this out?
let attributedString = NSMutableAttributedString(string: displayName, attributes: [NSParagraphStyleAttributeName: paragraphStyle, NSFontAttributeName : UIFont(name: "SFUIDisplay-Regular", size: 18)])
var newFrame = attributedString.boundingRectWithSize(CGSizeMake(self.frame.size.width-usernameX-horizontalMargin, CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin , context: nil)
username.frame = CGRect(x: usernameX, y: (self.frame.size.height/2)-21, width: newFrame.size.width, height: newFrame.size.height)
If you want to use sizeThatFits you can use following
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.hyphenationFactor = 0.2
username.attributedText = NSMutableAttributedString(string: displayName, attributes: [NSParagraphStyleAttributeName: paragraphStyle, NSFontAttributeName : UIFont(name: "SFUIDisplay-Regular", size: 18)])
let maxSize = CGSize(width: self.frame.size.width-usernameX-horizontalMargin, height: CGFloat.max)
let requiredSize = username.sizeThatFits(maxSize)
username.frame = CGRect(x: usernameX, y: (self.frame.size.height/2)-21, width: requiredSize.width, height: requiredSize.height)
self.addSubview(username)

Resources