CATextLayer not visible - ios

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?

Related

UILabel custom Text

How can I make this text using single UILabel or give any other solution to achieve this design.
You can use NSTextAttachment for that behaviour. I modify this for position of attachment.
All code :
#IBOutlet weak var lbl: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let string = "Urban points users average montly saving is "
let normalNameString = NSMutableAttributedString.init(string: string)
let attachment = NSTextAttachment()
attachment.image = imageHelper.pgImage(textValue: "QAR 115 ", lbl: lbl)
attachment.bounds = CGRect(x: 0, y: (lbl.font.capHeight - attachment.image!.size.height).rounded() / 2, width: attachment.image!.size.width, height: attachment.image!.size.height)
normalNameString.append(NSAttributedString(attachment: attachment))
normalNameString.append(NSAttributedString(string: "You have saved "))
let attachment2 = NSTextAttachment()
attachment2.image = imageHelper.pgImage(textValue: "QAR 29",textColor: UIColor.yellow,backgroundColor: UIColor.black , lbl: lbl)
attachment2.bounds = CGRect(x: 0, y: (lbl.font.capHeight - attachment2.image!.size.height).rounded() / 2, width: attachment2.image!.size.width, height: attachment2.image!.size.height)
normalNameString.append(NSAttributedString(attachment: attachment2))
normalNameString.append(NSAttributedString(string: " this month"))
lbl.attributedText = normalNameString
}
}
class imageHelper{
static func pgImage(textValue:String,textColor : UIColor = UIColor.white , backgroundColor : UIColor = UIColor.red,lbl : UILabel) ->UIImage{
let label = UILabel(frame: CGRect(x: 0, y: 0, width: (textValue as NSString).size(withAttributes: [NSAttributedString.Key.font : lbl.font!]).width, height: lbl.frame.size.height))
label.font = lbl.font
label.textAlignment = .center
label.textColor = textColor
label.backgroundColor = backgroundColor
label.layer.borderColor = UIColor.darkGray.cgColor
label.layer.borderWidth = 1
label.layer.cornerRadius = label.frame.size.height/2
label.layer.masksToBounds = true
label.text = textValue
label.numberOfLines = 1
UIGraphicsBeginImageContextWithOptions(label.bounds.size, false,UIScreen.main.scale)
label.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
And the result is :

Text color in the HUD

Here is my code:
override func draw(_ rect: CGRect) {
let boxWidth: CGFloat = 96
let boxHeight: CGFloat = 96
let boxRect = CGRect(x: round((bounds.size.width - boxWidth) / 2),
y: round((bounds.size.height - boxHeight) / 2),
width: boxWidth, height: boxHeight)
let roundedRect = UIBezierPath(roundedRect: boxRect, cornerRadius: 10)
UIColor(white: 0.3, alpha: 0.8).setFill()
roundedRect.fill()
if let image = UIImage(named: "Checkmark") {
let imagePoint = CGPoint(
x: center.x - round(image.size.width / 2),
y: center.y - round(image.size.height / 2) - boxHeight / 8)
image.draw(at: imagePoint)
}
let attribs = [ kCTFontAttributeName: UIFont.systemFont(ofSize: 66.0), kCTForegroundColorAttributeName: UIColor.white]
let textSize = text.size(withAttributes: attribs as [NSAttributedString.Key : Any])
let textPoint = CGPoint(
x: center.x - round(textSize.width / 2),
y: center.y - round(textSize.height / 2) + boxHeight / 4)
text.draw(at: textPoint, withAttributes: attribs as [NSAttributedString.Key : Any])
}
The text color in the HUD is black. Why and how can I change it to white ?
You should use NSAttributedString.Key instead of CoreText keys try to replace this:
let attribs = [ kCTFontAttributeName: UIFont.systemFont(ofSize: 66.0), kCTForegroundColorAttributeName: UIColor.white]
with this:
let attribs: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: 66.0),
.foregroundColor: UIColor.green]
You can change it on this line
let attribs = [ kCTFontAttributeName: UIFont.systemFont(ofSize: 66.0), kCTForegroundColorAttributeName: UIColor.white.CGColor]
The foreground color of the text to which this attribute applies. The value associated with this attribute must be a CGColor object. Default value is black. Refer here
Try this:
let attribs = [NSAttributedString.Key.font.rawValue: UIFont.systemFont(ofSize: 66.0), NSAttributedString.Key.foregroundColor: UIColor.white] as! [String : Any]

How to keep text horizontally during rotating transform of containing view

Making custom UI control, something like rotation wheel, looks like this:
As you can see labels positioned "on radiuses", but i need place all labels horizontal, and keep em same way when I will rotate container view
You can do something like this:
let font = UIFont.systemFont(ofSize: 12)
let attributes = [
NSAttributedString.Key.font: UIConstants.CaptionFont,
NSAttributedString.Key.foregroundColor: UIColor.accent
]
for path in pathsForIndicators {
let cgPath = path.cgPath
let layer = CATextLayer()
layer.frame = CGRect(x: cgPath.boundingBox.midX + offset + 22,
y: cgPath.boundingBox.midX + 10, width: 40, height: 40)
layer.position = CGPoint(x: cgPath.boundingBox.midX + offset + 22,
y: cgPath.boundingBox.midY + 10)
layer.font = font
let value = 0 // TODO
let title = String(describing: value)
let attributedString = NSAttributedString(string: title, attributes: attributes)
layer.string = attributedString
layer.isWrapped = false
layer.alignmentMode = CATextLayerAlignmentMode.center
layer.foregroundColor = indicatorColor.cgColor
layer.shouldRasterize = true
layer.needsDisplayOnBoundsChange = false
layer.needsDisplay()
layer.displayIfNeeded()
textLayer.addSublayer(layer)
}
textLayer.backgroundColor = UIColor.clear.cgColor
textLayer.bounds = bounds
textLayer.position = centerPoint
layer.addSublayer(textLayer)

Stroke text attributes for title in navigation bar are not applied

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

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