How to add an image with text to a PDFTableCell? - ios

I need something like this (green square):
enter image description here
I've tried adding attributedString with an image attached to the cell, but that doesn't work. Do you have any ideas?
let attachmentImage = NSTextAttachment()
attachmentImage.image = serviceImage.image
attachmentImage.bounds = CGRect(x: 0, y: 0, width: 14, height: 14)
let attrString = NSMutableAttributedString(
string: "Text followed by an image",
attributes: [
.font: regularFont
])
attrString.append(NSAttributedString(attachment: attachmentImage))
let imageCell = table[position: PDFTableCellPosition(row: 0, column: 0)]
imageCell.content = try? PDFTableContent(content: attrString)

Related

something wrong with UIButton setImage

I am attempting to make my own custom Facebook login button. I am close, but for some reason when I setImage on the UIButton it still has a really large frame that is pushing the text to the right and the icon to the right as well.
What am I missing? I tried setting the frame and that did not help.
(The actual image is large, but .scaleAspetFit makes it look perfect, but I think the frame persists?)
let customFacebookButton: UIButton = {
let view = UIButton()
view.setImage(UIImage(named: "fb-logo"), for: .normal)
view.imageEdgeInsets = UIEdgeInsetsMake(8, 8, 8, 4)
view.imageView?.contentMode = .scaleAspectFit
view.backgroundColor = UIColor.init(hex: "3B5998")
view.layer.cornerRadius = 6
let mutableAttributedString = NSMutableAttributedString()
let attributes: [NSAttributedStringKey: Any] = [
NSAttributedStringKey.font : UIFont.systemFont(ofSize: 14),
NSAttributedStringKey.foregroundColor : UIColor.init(hex: "#EFEFEF") ]
let string = NSMutableAttributedString(string: "Continue with Facebook", attributes: attributes)
mutableAttributedString.append(string)
view.setAttributedTitle(mutableAttributedString, for: .normal)
return view
}()
It is because of the size of image. Reduce the size of image. It will work perfectly.
I have tested you code with two image sizes 512*512 and 80*80.
512*512
https://i.stack.imgur.com/zuRWo.png
80*80
https://i.stack.imgur.com/YvID9.png
for left align the image:
view.contentHorizontalAlignment = .left
There is no way to centre the title with left align image. Temporally you can change titleEdgeInsets to do that:
view.titleEdgeInsets = UIEdgeInsetsMake(8, 16, 8, 4)
OR
You can take a imageView to the left of button. And remove the image as part of button. then centre align the contentHorizontalAlignment.
Code:
let customFacebookButton: UIButton = {
let view = UIButton()
// view.setImage(UIImage(named: "logo"), for: .normal)
// view.imageEdgeInsets = UIEdgeInsetsMake(8, 8, 8, 4)
view.backgroundColor = UIColor.blue
view.layer.cornerRadius = 6
view.contentHorizontalAlignment = .center
let mutableAttributedString = NSMutableAttributedString()
let attributes: [NSAttributedStringKey: Any] = [
NSAttributedStringKey.font : UIFont.systemFont(ofSize: 14),
NSAttributedStringKey.foregroundColor : UIColor.white ]
let string = NSMutableAttributedString(string: "Continue with Facebook", attributes: attributes)
mutableAttributedString.append(string)
view.setAttributedTitle(mutableAttributedString, for: .normal)
return view
}()
customFacebookButton.frame = CGRect.init(x: 10, y: 20, width: 300, height: 40)
self.view.addSubview(customFacebookButton)
let imageView = UIImageView.init(frame: CGRect.init(x: 12, y: 22, width: 38, height: 38))
imageView.image = #imageLiteral(resourceName: "logo")
self.view.addSubview(imageView)
Output:

how to change color of the part of header title in tableView in swift 3?

I have read similar questions But I didn't got the answer :
I have Table View With Headers and the first one has title and a number I want to change the color of that number in the header in table view
here is my codes :
var headerList = ["Account" , "Help" , "" ]
override func viewDidLoad() {
super.viewDidLoad()
self.headerList[0] = "Account \(userAccountMoney)"
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let returnedView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 25))
returnedView.backgroundColor = UIColor.init(red: 229/255, green: 233/255, blue: 236/255, alpha: 1.0)
let label = UILabel(frame: CGRect(x: -20, y: 7, width: view.frame.size.width, height: 25))
label.text = self.headerList[section]
label.textAlignment = .right
label.textColor = .lightGray
}
as you See in my codes the header Titles Are Gray But I want in the first header Title the Account word Still be Gray But the userAccountMoney be the Green the problem is that because userAccountMoney is another variable I couldn't use similar questions
If you want to change the color of a part of a string you need to use NS(Mutable)AttributedString and add the color attribute only to the specific range:
if section == 0 {
let sectionTitle = self.headerList[0]
let attributedString = NSMutableAttributedString(string: sectionTitle)
if sectionTitle.characters.count > 8 {
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: NSRange(location: 8, length: sectionTitle.characters.count - 8))
}
label.attributedText = attributedString
} else {
label.text = self.headerList[section]
}
The index 8 is the hard-coded index after "Account "
However in your case I'd recommend to create headerList as constant
let headerList = ["" , "Help" , "" ]
then delete the code in viewDidLoad and use this code to create the account amount dynamically
if section == 0 {
let attributedString = NSMutableAttributedString(string: "Account ")
attributedString.append(NSAttributedString(string: "\(userAccountMoney)", attributes: [NSForegroundColorAttributeName : UIColor.red]))
label.attributedText = attributedString
} else {
label.text = self.headerList[section]
}
Using NSAttributedString you can create two multiple colour text, even you can change the font. Here is the snippet:
let titleAtt = NSAttributedString(string: "Hello", attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 18.0)!, NSForegroundColorAttributeName: UIColor.blue])
let numberAtt = NSAttributedString(string: "123", attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 18.0)!, NSForegroundColorAttributeName: UIColor.red])
let combinationAtt = NSMutableAttributedString()
combinationAtt.append(titleAtt)
combinationAtt.append(numberAtt)
label.attributedText = combinationAtt
You can achieve it by writing like below code:
I have created one common function to reuse it in every controller.
//MARK:- Set title with two different color
func setTitle(title : String, loc : Int, len : Int) -> NSMutableAttributedString
{
let myMutableString = NSMutableAttributedString(
string: title,
attributes: [:])
myMutableString.addAttribute(
NSForegroundColorAttributeName,
value: UIColor(red: 29/255, green: 140/255, blue: 242/255, alpha: 1.0),
range: NSRange(
location:loc,
length:len))
return myMutableString
}
I am using this fuction like,
For same controller you can write it,
self.lblTitle.attributedText = self.setTitle(title: "My Profile", loc: 3, len: 7)
You can also use this to change color of specific characters. You need to specify lenght of string and starting location of characters.
I might not understand your problem completely but I think you want to set different color for your first tableview header.
You want do this by using If-else statement on section variable.
Like this
func setAttributedString(text string : String, subStringRange range : NSRange, subStringFont font1 : UIFont, mainStringFont font2 : UIFont, subStringColor color1 : UIColor = UIColor.gray, mainStringColor color2 : UIColor = UIColor.green) -> NSAttributedString {
let mainStringAttribute = [ NSFontAttributeName: font2, NSForegroundColorAttributeName : color2] as [String : Any]
let attributedString = NSMutableAttributedString(string: string, attributes: mainStringAttribute)
let subStringAttribute = [ NSFontAttributeName: font1, NSForegroundColorAttributeName : color1] as [String : Any]
attributedString.addAttributes(subStringAttribute, range: range)
return attributedString
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if (section == 0) // this is first header
{
let returnedView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 25))
returnedView.backgroundColor = UIColor.init(red: 229/255, green: 233/255, blue: 236/255, alpha: 1.0)
let label = UILabel(frame: CGRect(x: -20, y: 7, width: view.frame.size.width, height: 25))
label.text = self.headerList[section]
label.textAlignment = .right
let font1 = UIFont.systemFont(ofSize: 14.0)
let font2 = UIFont.systemFont(ofSize: 14.0)
label.attributedText = setAttributedString(text: "", subStringRange: NSRange(location: 0, length: 1), subStringFont: font1, mainStringFont: font2)
}
else /// remaining headers
{
let returnedView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 25))
returnedView.backgroundColor = UIColor.init(red: 229/255, green: 233/255, blue: 236/255, alpha: 1.0)
let label = UILabel(frame: CGRect(x: -20, y: 7, width: view.frame.size.width, height: 25))
label.text = self.headerList[section]
label.textAlignment = .right
label.textColor = .lightGray
}
}

why multiline attributedString UITextView has a different line height?

I get different line height in textView with using same font
How to set fixed line height?
I have done a lot of attempts, any help is appreciated, thanks
set NSMutableParagraphStyle lineSpacing is useless
set lineHeightMultiple is to make the difference more obvious
[
demo
import UIKit
import PlaygroundSupport
let view = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 1000))
let data: [String] = [
"商品名称: 巧克力",
"商品名称: 巧克力",
"商品名称: 巧克力",
"注册未成功,请验证电子邮件",
"注册未成功,请验证电子邮件",
"注册未成功,请验证电子邮件",
"测试文字, 测试文字,测试文字",
"测试文字, 测试文字,测试文字",
"测试文字, 测试文字,测试文字",
]
let textView = UITextView(frame: view.frame)
let paragraphStyle = NSMutableParagraphStyle()
let bodyFont = UIFont.systemFont(ofSize: 20.0)
paragraphStyle.lineHeightMultiple = 4
var stripe = false
// attributedString
let mutableAttributedString = NSMutableAttributedString(string: "Test TextViewAttributedString\n", attributes: [
NSFontAttributeName: UIFont.systemFont(ofSize: 18.0)
])
for text: String in data {
var backgroundColor = UIColor(red:0.13, green:0.38, blue:0.95, alpha:1.00)
if stripe {
backgroundColor = UIColor(red:0.92, green:0.12, blue:0.38, alpha:1.00)
}
let contentAttributedString = NSAttributedString(string: text, attributes: [
NSBackgroundColorAttributeName: backgroundColor,
NSParagraphStyleAttributeName: paragraphStyle,
NSFontAttributeName: bodyFont
])
mutableAttributedString.append(contentAttributedString)
stripe = !stripe
// add newline character
let newlineAttributedString = NSAttributedString(string: "\n")
mutableAttributedString.append(newlineAttributedString)
}
textView.attributedText = mutableAttributedString
view.addSubview(textView)
PlaygroundPage.current.liveView = view
I found the reason, the newlineAttributedString also need NSFontAttributeName
let newlineAttributedString = NSAttributedString(string: "\n", attributes: [
NSFontAttributeName: bodyFont
])
mutableAttributedString.appendAttributedString(newlineAttributedString)

NSAttributedString not displaying correctly

I want my UILabel to be able to split a long name into two lines and add the hyphen. Currently my code is like so :
let usernameX = profilePhoto.frame.size.width+horizontalMargin
let username = UILabel(frame: CGRect(x: usernameX, y: (self.frame.size.height/2)-21, width: self.frame.size.width-usernameX-horizontalMargin, height: 42))
username.adjustsFontSizeToFitWidth = true
username.font = UIFont(name: "SFUIDisplay-Regular", size: 20)
username.minimumScaleFactor = 0.8
username.numberOfLines = 2
username.translatesAutoresizingMaskIntoConstraints = false
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.hyphenationFactor = 0.5
let attributedString = NSMutableAttributedString(string: "Areallylongname", attributes: [NSParagraphStyleAttributeName: paragraphStyle])
However the label is only displaying "Areally-". What am I doing wrong here?
You can re-check the height of superview of label.
Fixing 42 as height is not the correct way to do it. You can calculate height of the label required dynamically and assign it. You can do it following way.
let attributedString = NSMutableAttributedString(string: "Areallylongname", attributes: [NSParagraphStyleAttributeName: paragraphStyle, NSFontAttributeName : UIFont(name: "SFUIDisplay-Regular", size: 20)])
var newFrame = attributedString.boundingRectWithSize(CGSizeMake(username.frame.size.width, 9999), options: NSStringDrawingOptions.UsesLineFragmentOrigin , context: nil)
newFrame.origin.x = username.frame.origin.x
newFrame.origin.y = username.frame.origin.y
You can set the new frame in viewDidLayoutSubviews

How to concatenate two UITextView

I'm trying to concatenate two UItextView and it work.
They have different properties (for example different UIFont) but in the final UITextView they have the same properties. How to fix this?
textViewFirst!.text = "\n Example"
textViewFirst!.font = UIFont(name: "Helvetica Neue", size: 10);
textViewSecond.text = textViewSecond.text + textViewFirst.text
for example : this makes your text bold from the 4th char to 7th
let myFullString:String = textViewSecond.text + textViewFirst.text as String
var attributedText: NSMutableAttributedString = NSMutableAttributedString(string: myFullString)
attributedText.addAttributes([NSFontAttributeName: UIFont.boldSystemFontOfSize(14)], range: NSRange(location: 3, length: 3))
textViewSecond.attributedText = attributedText
Try this:
var attributedString = NSMutableAttributedString(string: textView2.text, attributes: [NSFontAttributeName : textView2.font])
attributedString.appendAttributedString(NSAttributedString(string: textView1.text, attributes: [NSFontAttributeName : textView1.font]))
textView2.attributedText = attributedString
In order to preserve both fonts and maybe other attributes (like text color) you must make use of NSAttributedString
let font = UIFont(name: "Helvetica Neue", size: 10.0) ?? UIFont.systemFontOfSize(18.0)
let textFont = [NSFontAttributeName:font]
// Create a string that will be our paragraph
let para1 = NSMutableAttributedString()
let para2 = NSMutableAttributedString()
// Create locally formatted strings
let attrString1 = NSAttributedString(string: "Hello ", attributes:textFont)
let attrString2 = NSAttributedString(string: "World ", attributes:textFont)
// Add locally formatted strings to paragraph
para1.appendAttributedString(attrString1)
para2.appendAttributedString(attrString2)
// Define paragraph styling
let paraStyle = NSMutableParagraphStyle()
paraStyle.firstLineHeadIndent = 15.0
paraStyle.paragraphSpacingBefore = 10.0
// Apply paragraph styles to paragraph
para1.addAttribute(NSParagraphStyleAttributeName, value: paraStyle, range: NSRange(location: 0,length: para1.length))
para2.addAttribute(NSParagraphStyleAttributeName, value: paraStyle, range: NSRange(location: 0,length: para1.length))
// Create UITextView
let view1 = UITextView(frame: CGRect(x: 0, y: 20, width: CGRectGetWidth(self.view.frame), height: 100))
let view2 = UITextView(frame: CGRect(x: 0, y: 100, width: CGRectGetWidth(self.view.frame), height: 100))
let view3 = UITextView(frame: CGRect(x: 0, y: 200, width: CGRectGetWidth(self.view.frame), height: 100))
// Add string to UITextView
view1.attributedText = para1
view2.attributedText = para2
var attributedString = NSMutableAttributedString(string: view1.text, attributes: [NSFontAttributeName : view1.font])
attributedString.appendAttributedString(NSAttributedString(string: view2.text, attributes: [NSFontAttributeName : view2.font]))
view3.attributedText = attributedString
// Add UITextView to main view
self.view.addSubview(view1)
self.view.addSubview(view2)
self.view.addSubview(view3)

Resources