How to calculate boundRect correctly for NSAttributedString When apply shadow - swift

I tried apply shadow effect to UILabel using NSAttributeString. I want to change the size of UILabel whenever change shadow offset. However, it doesn't calculate correct frame and ignore shadow offset. How can I achieve?
let textView = UILabel(frame: CGRect(x: 20, y: 100, width: 300, height: 50))
textView.layer.borderColor = UIColor.red.cgColor
textView.layer.borderWidth = 1
textView.numberOfLines = 0
textView.text = "hyHgjpQ\nhyHgjpQ\nhyHgjpQ"
textView.font = UIFont(name: "DamascusSemiBold", size: 40)
textView.textColor = .white
textView.textAlignment = .center
self.view.addSubview(textView)
var textAttributes: [NSAttributedString.Key: AnyObject] = [:]
// font name & size
let font = UIFont(name: "HelveticaNeue", size: 50)
textAttributes[NSAttributedString.Key.font] = font
// shadow
let shadow = NSShadow()
shadow.shadowBlurRadius = 10
shadow.shadowOffset = CGSize(width: 10, height: 30)
shadow.shadowColor = UIColor.red
textAttributes[NSAttributedString.Key.shadow] = shadow
textView.attributedText = NSAttributedString(string: textView.text ?? "", attributes: textAttributes)
let bound = textView.text!.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude),
options: .usesLineFragmentOrigin,
attributes: textAttributes,
context: nil)
textView.bounds = bound
Result

Related

Add label in center of imageView

I have the two images like in the picture at the end of the question (the image of a list and a red dot). I want to add a label in the center of the red dot. This is my code that doesn't work:
image = UIImageView(image: UIImage(named: "pallino"))
image.frame = CGRect(x: 55, y: self.view.frame.height-60, width: 22, height: 22)
self.view.addSubview(image)
image.layer.cornerRadius = image.frame.width/2
label = UILabel(frame: CGRect(x: self.image.center.x, y: self.image.center.y, width: image.frame.size.width, height: image.frame.size.height))
label.text = "4"
label.font = UIFont(name:"HelveticaNeue-Bold", size: 15.0)
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = UIColor.black
image.addSubview(label)
Can someone tell me were am I wrong?
Problem in this line:
label = UILabel(frame: CGRect(x: self.image.center.x, y: self.image.center.y, width: image.frame.size.width, height: image.frame.size.height))
self.image.center.x - The center point is specified in points in the coordinate system of its superview, it is mean that self.image.center is not center of image
You need frame for label, something like this:
let imageSize = 22
let frame = CGRect(x: 0, y: 0, width: imageSize, height: imageSize)
let label = UILabel(frame: frame)
label.aligment = .center
You can set constraint in your label(centered Horizontally and Vertically). Try with the following code.
let label = UILabel()
label.text = "4"
label.font = UIFont(name:"HelveticaNeue-Bold", size: 15.0)
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = UIColor.black
image.addSubview(label)
label.centerXAnchor.constraint(equalTo: self.image.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: self.image.centerYAnchor).isActive = true
To center the label in UIImageView you can refer to this example which is tested and working solution.
extension UIImageView {
/// Create label programmatically
/// - Returns: UILabel
private func ageSensitiveLabel() -> UILabel {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height))
label.text = "Content"
label.font = .systemFont(ofSize: 5.0)
label.textAlignment = .center
label.numberOfLines = 0
label.minimumScaleFactor = 0.5
label.adjustsFontSizeToFitWidth = true
label.baselineAdjustment = .alignCenters
label.textColor = .white
return label
}
/// Add label as subview to UIImageView
func addAgeSensitiveLabel() {
self.subviews.forEach { view in
DispatchQueue.main.async {
view.removeFromSuperview()
}
}
self.addSubview(ageSensitiveLabel())
}
}
Use it with UIImageView
imageView.addAgeSensitiveLabel()

Why disappear navigationBar backButtonItem? Swift4

I use largeTitleBar.
When navigationBar.title has character over 20 bytes (in Case iPhone SE), backButtonItem.title disappears. (In case iPhoneX, 22 bytes)
navigationBar.title becomes truncate affects this problem.
But I don't have any idea to solve this problem.
navigationItem.title = someText
// when navigationItem.title is truncated, backButtonItem.title disappears.
self.title = "Your TiTle Text"
var lbl = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
lbl.text = navigationItem?.title
lbl.textColor = UIColor.white
if let fontSize = UIFont(name: "Helvetica-Bold", size: 30.0) {
lbl.font = fontSize
}
lbl.backgroundColor = UIColor.clear
lbl.adjustsFontSizeToFitWidth = true
lbl.textAlignment = .center
navigationItem?.titleView = lbl
Try above code may help you.

Clipped text on UILabel

I'm using custom a font for UILabel but there is a strange problem, for some characters the text is being clipped:
The label should be like this (label frame has enlarged manually):
This is the code to add the label to the gray view:
let string = "کیخسروی"
let font = UIFont(name: "IranNastaliq", size: 30)!
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byWordWrapping
paragraphStyle.alignment = .center
let attributes: [NSAttributedStringKey: Any] = [
.font: font,
.paragraphStyle: paragraphStyle
]
let mutabbleAttributedString = NSMutableAttributedString(string: string, attributes: attributes)
let rectSize = mutabbleAttributedString.size()
let label = UILabel(frame: CGRect(x: 0, y: 0, width: rectSize.width, height: rectSize.height))
label.font = font
label.attributedText = mutabbleAttributedString
label.backgroundColor = UIColor.yellow
label.textAlignment = .center
let size = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
let width = label.sizeThatFits(size).width
let height = label.sizeThatFits(size).height
let frame = CGRect(x: 0, y: 0, width: width, height: height)
label.frame = frame
self.myView.addSubview(label)
label.center = self.myView.center
Seems sizeThatFits() does not calculate the bounds correctly.
I have to mention this clipping only happens while using some custom fonts.

How to set button width based on text for dynamically created button in swift 3?

I created the dynamic buttons. I need to change the width of button based on tittle label text. Here is my code.
for i in 0..<holdingSize {
let button = UIButton(type: .custom)
if i == 0 {
frame = CGRect(x: 10, y: 5, width: 100, height: 30)
}else{
buttonY = buttonY + 110
frame = CGRect(x: buttonY, y: 5, width: 100, height: 30)
}
button.setTitle("\(arrayOfHoldings[i])", for: UIControlState.normal) // We are going to use the item name as the Button Title here.
button.titleLabel?.text = "\(arrayOfHoldings[i])"
button.titleLabel?.font = UIFont(name: (button.titleLabel?.font.fontName)!, size: 15)
button.setTitleColor(Colors.green, for: .normal)
button.sizeToFit()
}
Try this
func labelSizeWithString(text: String,fontSize: CGFloat, maxWidth : CGFloat,numberOfLines: Int) -> CGRect{
let font = UIFont.systemFontOfSize(fontSize)//(name: "HelveticaNeue", size: fontSize)!
let label = UILabel(frame: CGRectMake(0, 0, maxWidth, CGFloat.max))
label.numberOfLines = numberOfLines
label.font = font
label.text = text
label.sizeToFit()
return label.frame
}
This will give you the frame of the label, you can set the height of your button from that.
FOR SWIFT 3.0
func labelSize(for text: String,fontSize: CGFloat, maxWidth : CGFloat,numberOfLines: Int) -> CGRect{
let font = UIFont.systemFont(ofSize: fontSize)//(name: "HelveticaNeue", size: fontSize)!
let label = UILabel(frame: CGRect(x: 0, y: 0, width: maxWidth, height: CGFloat.leastNonzeroMagnitude))
label.numberOfLines = numberOfLines
label.font = font
label.text = text
label.sizeToFit()
return label.frame
}

UITextView not setting text

I've been breaking my head over this, but for some reason, I can't see any text that I set in the ".text" property. Below is my code:
var container = NSTextContainer(size: CGSize(width: 300, height: 200))
var textView = UITextView(frame: CGRect(x: 60, y: 90, width: 300, height: 200), textContainer: container)
destinationViewController.view.addSubview(textView)
textView.backgroundColor = UIColor.blueColor()
textView.textColor = UIColor.whiteColor()
textView.text = "Testing"
textView.textAlignment = NSTextAlignment.Natural
textView.font = UIFont(name:"Times New Roman", size: UIFont.systemFontSize())
textView.delegate = self
The backgroundColor is visible after the destination viewController loads, but the text isn't visible. What could I be doing wrong?