CATextlayer change size of FONT to fit the frame

I achieved it by doing this:

    float fontSize = InitialFontSize;
    UIFont *myFont = [UIFont boldSystemFontOfSize:fontSize];
    CGSize myFontSize = [YourTextHere sizeWithFont:myFont];
    while (myFontSize.width >= MaximunWidth) {
        fontSize -= 0.1f;
        myFont = [UIFont boldSystemFontOfSize:fontSize];
        myFontSize = [YourTextHere sizeWithFont:myFont];
    }
    CATextLayer *textLayer = [CATextLayer layer];
    [textLayer setFrame:CGRectMake(MaximunWidth - myFontSize.width / 2, MaximunHeight - myFontSize.height / 2, myFontSize.width, myFontSize.height)];
    [textLayer setFontSize:fontSize];
    [textLayer setString:YourTextHere];

    [textLayer setAlignmentMode:kCAAlignmentCenter];

Working for Swift 5 clean solution.

1) Extend String

extension String {
    func size(OfFont font: UIFont) -> CGSize {
        return (self as NSString).size(withAttributes: [NSAttributedString.Key.font: font])
    }
}

2) Subclass the CATextLayer

class DynamicTextLayer : CATextLayer {
    var adjustsFontSizeToFitWidth = false

    override func layoutSublayers() {
        super.layoutSublayers()
        if adjustsFontSizeToFitWidth {
            fitToFrame()
        }
    }

    func fitToFrame(){
        // Calculates the string size.
        var stringSize: CGSize  {
            get { return (string as? String)!.size(OfFont: UIFont(name: (font as! UIFont).fontName, size: fontSize)!) }
        }
        // Adds inset from the borders. Optional
        let inset: CGFloat = 2
        // Decreases the font size until criteria met
        while frame.width < stringSize.width + inset {
            fontSize -= 1
        }
    }
}

3) Now go to your code and instead of CATextLayer use DynamicTextLayer

textLayer = DynamicTextLayer()
textLayer?.alignmentMode = .center
textLayer?.fontSize = 40
textLayer?.string = "Example"
textLayer?.adjustsFontSizeToFitWidth = true