Caspert
Caspert

Reputation: 4363

How can I declare NSAttributedStringKey.font for custom font?

I want to calculate the height of the text to get the estimated height for the collection view cell. I use the following code inside collectionViewLayout function;

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    if let messageText = messages[indexPath.row]?.text {

        let size = CGSize(width: view.frame.width, height: 1000)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        let estimatedFrame = NSString(string: messageText).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 17)], context: nil)
        return CGSize(width: view.frame.width, height: estimatedFrame.height + 20)
    }

    return CGSize(width: view.frame.width, height: 100)
}

This is working for system fonts, but not for my custom font inside my project. The problem is that the estimatedFrame is not equal to the result with a system font. I think the problem will be the param of options: attributes. Is there a way like UIFont.systemFont(ofSize: 17) for custom fonts?

Upvotes: 0

Views: 904

Answers (1)

brandonscript
brandonscript

Reputation: 72855

If I'm reading your question right, you want:

UIFont(name: "yourCustomFontNameString", size: 17)

So:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    if let messageText = messages[indexPath.row]?.text {

        let size = CGSize(width: view.frame.width, height: 1000)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        let estimatedFrame = NSString(string: messageText).boundingRect(with: size, options: options, attributes: [NSAttributedStringKey.font: UIFont(name: "yourCustomFontNameString", size: 17)], context: nil)
        return CGSize(width: view.frame.width, height: estimatedFrame.height + 20)
    }

    return CGSize(width: view.frame.width, height: 100)
}

Upvotes: 3

Related Questions