Change icon position in swift 3 - ios

I have the following code which shows an icon on the left side of a uilabel, my question is how can I put the icon on the right side of the uilabel:
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "ic_person")
attachment.bounds = CGRect(x: 0, y: -3, width: 15, height: 15)
let attachmentStr = NSAttributedString(attachment: attachment)
let myString = NSMutableAttributedString(string: "")
myString.append(attachmentStr)
let myString1 = NSMutableAttributedString(string: item_empresa[indexPath.item].nombre_emp!)
myString.append(myString1)
cell.lbl_nombreEmpresa.attributedText = myString
Thanks in advance

You can put the image after the text by appending attachment after appending the text itself
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "ic_person")
attachment.bounds = CGRect(x: 0, y: -3, width: 15, height: 15)
let attributedString = NSMutableAttributedString(string: item_empresa[indexPath.item].nombre_emp ?? "")
attributedString.append(NSAttributedString(attachment: attachment))
cell.lbl_nombreEmpresa.attributedText = attributedString

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

iOS print NSAttributedString with images as NSTextAttachement to PDF

I'm trying to convert the content of an UITextView to PDF. The UITextView uses an NSAttributedString that contains text and images.
The images are instances of NSTextAttachment.
I went through the UIPrintPageRenderer way passing the UIPrintFormatter that I get from the UITextView through its viewPrintFormatter() function and it works perfectly for the text but I can't see any of the images. It looks like the images are actually taking up space as I can see the empty space between text lines, but no image is being rendered.
I suspect it might be the formatter, but I don't know how to work around it.
Any help is greatly appreciated.
The code I'm using to create the PDF from the NSAttributedString is the following:
public func createPDF(text: NSAttributedString, documentPath: URL, customPrintFormatter: UIPrintFormatter? = nil) {
let printFormatter = customPrintFormatter == nil ? UISimpleTextPrintFormatter(attributedText: text) : customPrintFormatter!
let renderer = UIPrintPageRenderer()
renderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
// A4 size
let pageSize = CGSize(width: 595.2, height: 841.8)
// create some sensible margins
let pageMargins = UIEdgeInsets(top: 72, left: 72, bottom: 72, right: 72)
// calculate the printable rect from the above two
let printableRect = CGRect(x: pageMargins.left, y: pageMargins.top, width: pageSize.width - pageMargins.left - pageMargins.right, height: pageSize.height - pageMargins.top - pageMargins.bottom)
// and here's the overall paper rectangle
let paperRect = CGRect(x: 0, y: 0, width: pageSize.width, height: pageSize.height)
renderer.setValue(NSValue(cgRect: paperRect), forKey: "paperRect")
renderer.setValue(NSValue(cgRect: printableRect), forKey: "printableRect")
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, paperRect, nil)
renderer.prepare(forDrawingPages: NSMakeRange(0, renderer.numberOfPages))
let bounds = UIGraphicsGetPDFContextBounds()
for i in 0 ..< renderer.numberOfPages {
UIGraphicsBeginPDFPage()
renderer.drawPage(at: i, in: bounds)
}
UIGraphicsEndPDFContext()
do {
try pdfData.write(to: documentPath)
} catch {
print(error.localizedDescription)
}
}
The following is the code that creates the NSTextAttachment
let attachment = NSTextAttachment()
attachment.image = UIImage.init(named: "1.png")
attachment.bounds = CGRect.init(x: 0, y: 0, width: 200, height: 100)
let img = NSMutableAttributedString.init(attachment: attachment)
let imgRange = NSRange.init(location: match.range(at: 0).location + match.range(at: 0).length, length: img.length)
self.beginEditing()
backingStore.insert(img, at: match.range(at: 0).location + match.range(at: 0).length)
let r = NSMakeRange(match.range(at: 0).location + match.range(at: 0).length, img.length)
self.edited([.editedCharacters, .editedAttributes], range: range, changeInLength: img.length)
self.endEditing()

Setting attributed label as navigation title

I am working on IOS using swift 4. I have to make the Navigation controller, with the center Aligned App title with Image at its left. But I am not getting how to attach image to its left. The attributed Image always goes to its right.
For this I am appending the string twice. below is the code
//Get image and set it's size
let image = UIImage(named: "user2")
let newSize = CGSize(width: 30, height: 30)
//Resize image
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
image?.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
let imageResized = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
//Create attachment text with image
let attachment = NSTextAttachment()
attachment.image = imageResized
let attachmentString = NSAttributedString(attachment: attachment)
let myString = NSMutableAttributedString(string: "")
myString.append(attachmentString)
let strAttachment = NSAttributedString(string: "My Ios App" )
myString.append(strAttachment)
navLabel.attributedText = myString
self.navigationItem.titleView = navLabel
What I am getting is some thing like below image is on left
what I want :
I just want the image to be shown with the space between text and Image.
I want the image to be look good and nice. Text should be center vertically to the image. what is good way of achieving this ?.
Using this code you will get your output :
let navgationView = UIView()
let label = UILabel()
label.text = " My Ios App"
label.sizeToFit()
label.center = navgationView.center
label.textAlignment = NSTextAlignment.center
let image = UIImageView()
image.image = UIImage(named: "user")
let imageAspect = image.image!.size.width/image.image!.size.height
image.frame = CGRect(x: label.frame.origin.x-label.frame.size.height*imageAspect, y: label.frame.origin.y, width: label.frame.size.height*imageAspect, height: label.frame.size.height)
image.contentMode = UIViewContentMode.scaleAspectFit
navgationView.addSubview(label)
navgationView.addSubview(image)
self.navigationItem.titleView = navgationView
navgationView.sizeToFit()
Output:-
Hope it's helps.!!
If you want to adjust your attachment position you must use the attachment.bounds property and if you want to adjust the text vertical alignment you need to use NSAttributedString baselineOffset key
Update
Swift 3 code
let normalNameString = NSMutableAttributedString.init(string: "")
let attachment = NSTextAttachment()
attachment.image = imageHelper.pgImage(textValue: "PG-13")
attachment.bounds = CGRect(x: 0, y: 0, width: (attachment.image?.size.width)!, height: (attachment.image?.size.height)!)
normalNameString.append(NSAttributedString(attachment: attachment))
normalNameString.append(NSAttributedString(string: " My Ios App", attributes: [NSBaselineOffsetAttributeName :6]))
self.lblText.attributedText = normalNameString
Swift 4 code
let normalNameString = NSMutableAttributedString.init(string: "")
let attachment = NSTextAttachment()
attachment.image = imageHelper.pgImage(textValue: "PG-13")
attachment.bounds = CGRect(x: 0, y: 0, width: (attachment.image?.size.width)!, height: (attachment.image?.size.height)!)
normalNameString.append(NSAttributedString(attachment: attachment))
normalNameString.append(NSAttributedString(string: " My Ios App", attributes: [NSAttributedStringKey.baselineOffset :6]))
self.lblText.attributedText = normalNameString
Swift 5 Update
let normalNameString = NSMutableAttributedString.init(string: "")
let attachment = NSTextAttachment()
attachment.image = imageHelper.pgImage(textValue: "PG-13")
attachment.bounds = CGRect(x: 0, y: 0, width: (attachment.image?.size.width)!, height: (attachment.image?.size.height)!)
normalNameString.append(NSAttributedString(attachment: attachment))
normalNameString.append(NSAttributedString(string: " My Ios App", attributes: [NSAttributedString.Key.baselineOffset :6]))
self.lblText.attributedText = normalNameString

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)

How to dynamically draw image for button in iOS?

This is the result I need to accomplish:
I need the icons with basic image: basket and additionally I need to put there UILabel with some text: once it is just a number, and once it is an amount to pay. Any ideas?
This is my example:
var image = UIImage(named: "cart")!
let text = "1 PLN"
UIGraphicsBeginImageContext(CGSizeMake(80, 50))
let context = UIGraphicsGetCurrentContext()
let label = UILabel(frame: CGRectZero)
label.text = text
label.font = UIFont.systemFontOfSize(10)
label.sizeToFit()
let width = max(label.frame.size.width + 10, 15)
let height = CGFloat(15)
CGContextSetFillColorWithColor(context, UIColor.greenColor().CGColor)
CGContextFillRect(context, CGRectMake(0, 0, image.size.width, image.size.height))
image.drawInRect(CGRectMake(80/2-50/2, 0, 50, 50))
let path = UIBezierPath(roundedRect: CGRectMake(75-width, 45-height, width, height), cornerRadius: 5)
path.lineWidth = 2
UIColor.redColor().setStroke()
UIColor.yellowColor().setFill()
path.stroke()
path.fill()
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.Center
let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(10.0), NSParagraphStyleAttributeName: paragraphStyle]
(text as NSString).drawInRect(CGRectMake(75-width, 45-height, width, height), withAttributes: attributes)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
The result is following:
Some examples for different text:

Resources