I'm trying to add two part of text with different font parameters.
But they always get value from first string.
And there one strange thing, font color is set independently.
let descriptionTextView: UITextView = {
let view = UITextView()
let attributedText = NSMutableAttributedString(string: "Text", attributes:
[.font:UIFont.boldSystemFont(ofSize: 20),
.foregroundColor: UIColor.blue])
attributedText.append(NSAttributedString(string: "\n\n\n Other text", attributes:
[.font: UIFont.italicSystemFont(ofSize: 5),
.foregroundColor: UIColor.gray]))
view.attributedText = attributedText
view.translatesAutoresizingMaskIntoConstraints = false
view.textAlignment = .center
view.font = UIFont.boldSystemFont(ofSize: 20)
view.isEditable = false
view.isScrollEnabled = false
return view
}()
This is how it look in simulator
Remove
view.font = UIFont.boldSystemFont(ofSize: 20)
Related
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
I have a UIStackView with three subviews in it: a title (UILabel), a body (UILabel), and a post image (UIImageView). This last image only gets added when the post has an imageURL (this is optional.)
Looking below, you can see that when I display the image, the UILabel disappears from out of the stackView somehow. How do I fix this?
P.S. Looking ahead, I am going to want to remove imageViews when the user is scrolling from those posts that lack imageViewURLs. Any tips on how to proceed here? Thank you again in advance.
Below is the relevant code:
class FeedTableViewCell: UITableViewCell {
//MARK: Public properties
var post: Post?{
didSet{
guard let post = post else {return}
// Adding user's name
let attributedText = NSMutableAttributedString(string: post.author.name + " → " + post.group.name, attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14)])
// Adding date and user's first name
let dateFormatter = PostDateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .short
attributedText.append(NSAttributedString(string: "\n" + dateFormatter.string(from: post.createdAt), attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12), NSAttributedString.Key.foregroundColor: UIColor(r: 155/255, g: 161/255, b: 171/255)]))
// Increasing Spacing
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 4
attributedText.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attributedText.length))
titleLabel.attributedText = attributedText
// Setting profile image
iconImageView.setImage(for: post.author, setContentMode: .scaleAspectFit)
messageTextView.text = post.content
setupImageSubviews()
}
}
//MARK: Private implementation
private let iconImageView = CircleImageView(size: 44)
private let titleLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.font = UIFont.systemFont(ofSize: 14)
label.textColor = .black
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private let messageTextView: UILabel = {
let labelView = UILabel()
labelView.numberOfLines = 0
labelView.font = UIFont.systemFont(ofSize: 14)
labelView.translatesAutoresizingMaskIntoConstraints = false
return labelView
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupDefaultViews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var stackView = UIStackView()
func setupDefaultViews(){
backgroundColor = UIColor.white
stackView.addArrangedSubview(titleLabel)
stackView.addArrangedSubview(messageTextView)
contentView.addSubview(iconImageView)
contentView.addSubview(stackView)
iconImageView.anchor(top: contentView.topAnchor, leading: contentView.leadingAnchor, bottom: nil, trailing: nil, padding: .init(top: 0, left: 8, bottom: 0, right: 0), size: CGSize(width: 44, height: 44))
stackView.anchor(top: contentView.topAnchor, leading: iconImageView.trailingAnchor, bottom: contentView.bottomAnchor, trailing: contentView.trailingAnchor, padding: .init(top: 0, left: 8, bottom: 8, right: 8))
stackView.axis = .vertical
}
private func setupImageSubviews() {
guard let imageURL = post?.imageURL else {return} // if no image exists, return, preventing image view from taking extra memory and performance to initialize and calculate constraints
// initialize here instead of globally, so it doesnt take extra memory holding this when no image exists.
let messageImageView: UIImageView = {
let imageView = UIImageView()
let contentImage = UIImage(systemName: "person.crop.circle.fill")!.withTintColor(.gray).withRenderingMode(.alwaysOriginal)
imageView.kf.setImage(with: imageURL, placeholder: contentImage)
imageView.contentMode = .scaleAspectFill
imageView.layer.masksToBounds = true
imageView.layer.borderWidth = 1
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
stackView.addArrangedSubview(messageImageView)
}}
Just so people know how I fixed this, I was attempting to use one cell template which would handle two different kinds of cells. That is a mistake, instead use the information in this link Using Auto Layout in UITableView for dynamic cell layouts & variable row heights to properly create two cell templates. I also found this code guaranteed that the cells were properly displaying the titles:
// Keeps the title text always showing
override func didMoveToSuperview() {
super.didMoveToSuperview()
layoutIfNeeded()
}
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
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
}
}
I would like to customize my navigation title but run into a problem. "String is not identical to NSObject". Can someone point me in the right direction? My code is below,
let font = UIFont(name: "HelveticaNeue", size: 15.0)
let textFont = [NSFontAttributeName: font]
let navText = [NSAttributedString(string: "MY STRING HERE", attributes: textFont)]
var navString = UILabel()
navString.appendAttributedString(navText)
self.navigationItem.titleView = navString
UPDATE: I was able to solve the problem with the following code,
var navString: NSString = "MY STRING HERE"
var completedNavString = NSMutableAttributedString()
completedNavString = NSMutableAttributedString(string: navString as String, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 18.0)!])
var navLabel = UILabel()
navLabel.attributedText = completedNavString
navLabel.sizeToFit()
self.navigationItem.titleView = navLabel
var navString = UILabel()
navString.appendAttributedString(navText)
You can't "append" anything to a UILabel. Try navString.attributedText = navText.