iOS change the color of links for uilabel when using NSAttributedString - swift

I'm using a uilabel and adding a link to by using NSAttributedString
let attributedText = NSMutableAttributedString(string: "http://www.google.com")
attributedText.addAttributes([NSAttributedString.Key.link: "https://www.google.com"], range: NSRange(location: 0, length: 21))
attributedText.addAttributes([NSAttributedString.Key.foregroundColor: UIColor.red], range: NSRange(location: 0, length: 21))
label.attributedText = attributedText
label.tintColor = UIColor.red
How can get the link to be another color other than the other default blue link color provided by the UIKit framework.
Note: I do not want to use UITextView or UIWebView

let attributedText = "http://www.google.com"
let multipleAttributes: [NSAttributedString.Key : Any] = [
NSAttributedString.Key.foregroundColor: UIColor.red,
NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue ]
let attributeString = NSAttributedString(string: attributedText, attributes: multipleAttributes)
// set attributed text on a UILabel
label.attributedText = attributeString

Related

How can you change the Header View title font on FSCalendar and add a Subtitle?

I am trying to set the header title font to a much larger style font more like a big banner, and set a subtitle underneath it of the year.
extension FSCalendar {
func customizeCalendar() {
appearance.caseOptions = [.headerUsesUpperCase]
appearance.headerDateFormat = "MMM"
headerHeight = 100
let header = FSCalendarHeaderView()
header.largeContentTitle?.append("aldjsf")
appearance.headerTitleFont = UIFont(name: "SFProDisplay-Bold", size: 200)
appearance.headerTitleColor = COLOR_BLACK
appearance.headerTitleOffset = CGPoint(x: 0, y: 0)
appearance.headerMinimumDissolvedAlpha = 0.6
appearance.todayColor = COLOR_PRIMARY
appearance.todaySelectionColor = COLOR_BLACK
appearance.titleFont = UIFont(name: "SFProDisplay-Bold", size: 11)
appearance.titleSelectionColor = COLOR_BLACK
appearance.weekdayFont = UIFont(name: "SFProText-Semibold", size: 11)
appearance.weekdayTextColor = COLOR_GREY
appearance.eventDefaultColor = COLOR_BLACK
appearance.subtitleFont = UIFont(name: "SFProDisplay-Bold", size: 20)
appearance.selectionColor = COLOR_BLACK
}
}
Even though I am accessing the property .headerTitleFont it doesn't do anything ? I have tried all kinds of sizes. Any help appreciated, thank you.
Issue with the Font sizes
Seems the font you have mentioned is not available in the simulator/device thus it defaults to a font. I tried your approach with a font which is pre-installed and the headerTitle got changed as expected. List of pre-installed fonts
appearance.headerTitleFont = UIFont(name: "Noteworthy Light", size: 60)
This is how it appears with the above font
Adding a subtitle to the headerView
With the available API, it seems you cannot set a subtitle in the headerView. But alternatively you can achieve it like below by customizing the FSCalendarHeaderCell.titleLabel.attributedText. Note that below code only change the text of collectionView.visibleCells, so you will also have to execute this code when you scroll the headerView
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
for cell in calendar.calendarHeaderView.collectionView.visibleCells {
//create an attributedString with two lines and different font sizes
let attributedString = NSMutableAttributedString(string: "Sep\n2021\n")
let attributes0: [NSAttributedString.Key : Any] = [
.foregroundColor: UIColor.yellow,
.font: UIFont(name: "HelveticaNeue", size: 40)!
]
let attributes1: [NSAttributedString.Key : Any] = [
.foregroundColor: UIColor.systemGray2
]
attributedString.addAttributes(attributes0, range: NSRange(location: 0, length: 3))
attributedString.addAttributes(attributes1, range: NSRange(location: 4, length: 4))
//replace titleLabel attributedText with the one we created
(cell as! FSCalendarHeaderCell).titleLabel.attributedText = attributedString
}
}
This is how it appears after changing the attributedText of the FSCalendarHeaderCell.titleLabel

How to change Searchbar's Placeholder font and size in iOS13

I read a couple of stack overflow entries to change a searchBar's placeholder text-attributes. However, in iOS13, none of them really work.
I wonder how the font, font-size and font-color of a searchBar Placeholder can be changed under iOS13 ?
Here is what I tried:
let myAttributes = [NSAttributedString.Key.font: UIFont(name: "Avenir-Heavy", size: 28) as Any]
navigationItem.searchController?.searchBar.placeholder =
NSAttributedString(string: "placeholder text", attributes: myAttributes).string
Swift 5:
if let textfield = searchBar.value(forKey: "searchField") as? UITextField {
let atrString = NSAttributedString(string: "Search",
attributes: [.foregroundColor : color,
.font : UIFont.systemFont(ofSize: 10, weight: .bold)])
textfield.attributedPlaceholder = atrString
}
You can use this method without accessing the value for key since searchbar has searchTextField property. Add this code after initialising your searchbar.
let placeholder = NSAttributedString(string: "your placeholder text", attributes: [.foregroundColor: UIColor.gray, NSAttributedString.Key.font: UIFont(name: "Helvetica", size: 15)!])
searchBar.searchTextField.attributedPlaceholder = placeholder

Why are NSAttributedString's attributes influencing other AttributedStrings?

In this case I'm setting a UILabel's attributedText with a combined NSAttributedString with different attributes for each line, and for some reason some AttributedString attributes influence the other AttributedStrings, but I thought their attributed are bound to the range of that particular AttributedString. I'm basically expecting that the NSAttributedString automatically gets its range set up when I append it to the NSMutableAttributedString.
Am I wrong?
In this case the shadows applies to the other appended AttributedStrings, in another case it is the bold font that overrides all fonts to come in the next AttributedStrings. Strange.
Here is some sample code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var textLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
textLabel.numberOfLines = 0
textLabel.lineBreakMode = .byWordWrapping
let myShadow = NSShadow()
myShadow.shadowBlurRadius = 3
myShadow.shadowOffset = CGSize(width: 3, height: 3)
myShadow.shadowColor = UIColor.gray
let attributedText = NSMutableAttributedString(string: "")
let fatString = NSMutableAttributedString(string: "Bold", attributes: [NSAttributedString.Key.foregroundColor : UIColor.green,
NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 16),
NSAttributedString.Key.backgroundColor : UIColor.lightGray,
NSAttributedString.Key.shadow : myShadow])
let normalString = NSAttributedString(string: "\n\nNormal", attributes: [NSAttributedString.Key.foregroundColor : UIColor.white,
NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)])
let italicString = NSAttributedString(string: "\n\nItalic", attributes: [NSAttributedString.Key.foregroundColor : UIColor.yellow,
NSAttributedString.Key.font : UIFont.italicSystemFont(ofSize: 16)])
let otherFontString = NSAttributedString(string: "\n\nBold + Italic", attributes: [NSAttributedString.Key.foregroundColor : UIColor.gray,
NSAttributedString.Key.font : UIFont(descriptor: UIFontDescriptor().withSymbolicTraits([.traitBold, .traitItalic])!, size: 16)])
let normalString2 = NSAttributedString(string: "\n\nUnderlined", attributes: [NSAttributedString.Key.underlineStyle : NSUnderlineStyle.single.rawValue,
NSAttributedString.Key.foregroundColor : UIColor.red,
NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)])
attributedText.append(fatString)
attributedText.append(normalString)
attributedText.append(italicString)
attributedText.append(otherFontString)
attributedText.append(normalString2)
textLabel.attributedText = attributedText
}
}

Can't change Paragraph attributes and String Attributes at the same time

I can get either the NSMutableParagraphStyle line spacing working OR the NSMutableAttributedString to be the correct font,color and size, but I can't get them both at the same time.
let style = NSMutableParagraphStyle()
style.lineSpacing = 5
let attributes = [NSParagraphStyleAttributeName : style]
aboutScrollable.attributedText = NSAttributedString(string: aboutScrollable.text, attributes:attributes)
let myString:NSString = aboutScrollable.text as NSString
var myMutableString = NSMutableAttributedString()
myMutableString = NSMutableAttributedString(string: myString as String, attributes: [NSFontAttributeName:UIFont(name: "Geomanist-regular", size: 12.0)!])
myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor(red: 30/255, green: 30/255, blue: 30/255, alpha: 1), range: NSRange(location: 0,length: aboutScrollable.text.characters.count))
// set label Attribute
aboutScrollable.attributedText = myMutableString; NSAttributedString(string: aboutScrollable.text, attributes:attributes)

UITextView frame doesn't care about the attributes of its content

I have a UITextView with an attributedText (containing font & lineSpacing to put lines closer).
I use the code below to determine the frame of the textView.
The problem is the frame.height is too much big, and doesn't seem to care about lineSpacing. It looks like the frame of the textView without specific lineSpacing.
Does anyone have an idea to fix this fail? Did I miss something?
//Attributes of textView
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = -1.25
let textViewText = Data().text
let attributedText = NSMutableAttributedString(string: textViewText, attributes: [NSFontAttributeName: UIFont(name: "AvenirNext-Medium", size: 14)!])
attributedText.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSRange(location: 0, length: attributedText.string.characters.count))
textView.attributedText = attributedText
...
//Determining the frame of textView in other method
let textViewText = Data().text
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = -1.25
let rect = NSString(string: textViewText).boundingRect(with: CGSize(width: view.bounds.size.width, height: view.bounds.size.height),
options: NSStringDrawingOptions.usesFontLeading.union(NSStringDrawingOptions.usesLineFragmentOrigin),
attributes: [NSFontAttributeName: UIFont(name: "AvenirNext-Medium", size: 14)!, NSParagraphStyleAttributeName: paragraphStyle],
context: nil)