1

I am trying to make fullname bold with boldFullName func. But obviously, it does not make any change on it. I believe that casting to string is deleting mutableString features. How can I avoid it without returning NSAttributedString

class NewNotificationModel: Serializable {
var fromUser: NewNotificationFromUserModel!
 }

class NewNotificationFromUserModel: Serializable {
var name: String!
var lastName: String!
}

final class NewNotificationViewModel {

// MARK: Properties
var notificationModel: NewNotificationModel!

private(set) var fullName: String!
 init(notificationModel: NewNotificationModel) {
    self.notificationModel = notificationModel
    self.fullName = boldFullName(getFullName())

 private func getFullName() -> String {
    guard let fromUser = notificationModel.fromUser, let name = fromUser.name, let lastname = fromUser.lastName else { return "" }
    return name + " " + lastname
}

func boldFullName(_ fullname: String) -> String {
    let range = NSMakeRange(0, getFullName().count)
    let nonBoldFontAttribute = [NSAttributedString.Key.font:UIFont.sfProTextSemibold(size: 16)]
    let boldFontAttribute = [NSAttributedString.Key.font:UIFont.catamaranBold(size: 20)]
    let boldString = NSMutableAttributedString(string: getFullName() as String, attributes:nonBoldFontAttribute)
        boldString.addAttributes(boldFontAttribute, range: range)
    return boldString.mutableString as String
}
}

And I am using this fullname in table cell as below

class NewNotificationTableViewCell: UITableViewCell, Reusable, NibLoadable {
@IBOutlet weak var messageLbl: UILabel!
 messageLbl.text = NewNotificationTableViewCell.configureText(model: model)

My configureText func is

private static func configureText(model: NewNotificationViewModel) -> String {
    guard let type = model.type else { return "" }
    switch NotificationType.init(rawValue: type) {
    String(format:"new_notification.group.request.want.join.text_%@_%@".localized, model.fullName, model.groupName ?? "")
    case .mention?: return String(format:"new_notification.post.mention_%@".localized, model.fullName)

But those .fullName does not do anything about bolding fullName.

Edited as NSAttributedString but this gives error

 case .internalCommunicationMessage?: return NSAttributedString(format:("new_notification.announcement.text_%@".localized), args: NSAttributedString(string: model.groupName ?? ""))

with this extension.

public extension NSAttributedString {
convenience init(format: NSAttributedString, args: NSAttributedString...) {
    let mutableNSAttributedString = NSMutableAttributedString(attributedString: format)

    args.forEach { (attributedString) in
        let range = NSString(string: mutableNSAttributedString.string).range(of: "%@")
        mutableNSAttributedString.replaceCharacters(in: range, with: attributedString)
    }
    self.init(attributedString: mutableNSAttributedString)
}

}

Cannot convert value of type 'String' to expected argument type 'NSAttributedString'

1
  • case .internalCommunicationMessage?: return NSAttributedString(format:"new_notification.announcement.text_%@".localized, model.groupName ?? "") is giving an error Extra argument in call Commented Mar 22, 2022 at 14:31

4 Answers 4

1

String doesn't contain attributes, you do need to return a NSAttributedString from your function.

What you can do instead is assigning the attributed string to the attributedText property of your UILabel. Documentation here

Example (after updating your function to return a NSAttributedString):

messageLbl.attributedText = NewNotificationTableViewCell.configureText(model: model)
Sign up to request clarification or add additional context in comments.

Comments

1

You need to assign messageLbl.attributedText

func boldFullName(_ fullname: String) -> NSAttributedString {
    let range = NSMakeRange(0, getFullName().count)
    let nonBoldFontAttribute = [NSAttributedString.Key.font:UIFont.sfProTextSemibold(size: 16)]
    let boldFontAttribute = [NSAttributedString.Key.font:UIFont.catamaranBold(size: 20)]
    let boldString = NSMutableAttributedString(string: getFullName() as String, attributes:nonBoldFontAttribute)
        boldString.addAttributes(boldFontAttribute, range: range)
    return boldString.mutableString
}

Comments

1

The main problem is you are trying to give attributedString to text property which is not gonna effect on the UILabel . You must change some part of your code like :

private(set) var fullName: String!

to :

private(set) var fullName: NSMutableAttributedString!

And

func boldFullName(_ fullname: String) -> String {
let range = NSMakeRange(0, getFullName().count)
let nonBoldFontAttribute = [NSAttributedString.Key.font:UIFont.sfProTextSemibold(size: 16)]
let boldFontAttribute = [NSAttributedString.Key.font:UIFont.catamaranBold(size: 20)]
let boldString = NSMutableAttributedString(string: getFullName() as String, attributes:nonBoldFontAttribute)
    boldString.addAttributes(boldFontAttribute, range: range)
return boldString.mutableString as String
}

to:

 func boldFullName(_ fullname: String) -> NSMutableAttributedString {
let range = NSMakeRange(0, getFullName().count)
let nonBoldFontAttribute = [NSAttributedString.Key.font:UIFont.systemFont(ofSize: 10)]
let boldFontAttribute = [NSAttributedString.Key.font:UIFont.systemFont(ofSize: 30)]
let boldString = NSMutableAttributedString(string: getFullName() as String, attributes:nonBoldFontAttribute)
    boldString.addAttributes(boldFontAttribute, range: range)
return boldString
}

And last when you call use attributedText instead of string

 messageLbl.attributedText = ...

Comments

0

with this extension

 convenience init(format: NSAttributedString, args: NSAttributedString...) {
    let mutableNSAttributedString = NSMutableAttributedString(attributedString: format)
    
    args.forEach { (attributedString) in
        let range = NSString(string: mutableNSAttributedString.string).range(of: "%@")
        mutableNSAttributedString.replaceCharacters(in: range, with: attributedString)
    }
    self.init(attributedString: mutableNSAttributedString)
}

I modified my switch cases as below

 case .internalCommunicationMessage?:
        let content = NSAttributedString(string:"new_notification.announcement.text_%@".localized)
        let gn = NSAttributedString(string: model.groupName ?? "", attributes: [.font: UIFont.sfProTextMedium(size: size),
                                                                                .kern: -0.26])
        return NSAttributedString(format: content, args: gn)

the changed return type of configureText

configureText(model: NewNotificationViewModel) -> NSAttributedString

deleted boldFullName function and changed fullName type back to String

and finally inserted as below to label.

messageLbl.attributedText = NewNotificationTableViewCell.configureText(model: model)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.