Search code examples
swiftuilabelnsattributedstring

NSAttribute Doesn't Make Bold Swift


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'


Solution

  • 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)