0

I am working on photo editing app. I want to put some label and images in a view which is named as 'stickerView'. All I want when content size in that view change the stickerview also change its height and width accordingly.

For sticker view I am using https://github.com/injap2017/StickerView this library.

its working fine with images but with label its not adjust label font according to view.

I use this class to set the font according to the view

import UIKit
class FlexiFontLabel: UILabel {
    // Boundary of minimum and maximum
    private let maxFontSize = CGFloat(100)
    private let minFontSize = CGFloat(15)
    
    // Margin of error is needed in binary search
    // so we can return when reach close enough
    private let marginOFError = CGFloat(0.5)
    
    // layoutSubviews() will get called while updating
    // font size so we want to lock adjustments if
    // processing is already in progress
    private var isUpdatingFontSize = false
    
    // Once this is set to true, the label should only
    // only support multiple lines rather than one
    var doesAdjustFontSizeToFitFrame = false
    {
        didSet
        {
            if doesAdjustFontSizeToFitFrame
            {
                numberOfLines = 0
            }
        }
    }
    
    // Adjusting the frame of the label automatically calls this
    override func layoutSubviews()
    {
        super.layoutSubviews()
        
        // Make sure the label is set to auto adjust the font
        // and it is not currently processing the font size
        if doesAdjustFontSizeToFitFrame
            && !isUpdatingFontSize
        {
            adjustFontSizeIfRequired()
        }
    }
    
    
    /// Adjusts the font size to fit the label's frame using binary search
    private func adjustFontSizeIfRequired()
    {
        guard let currentText = text,
              var currentFont = font else
        {
            print("failed")
            return
        }
        
        // Lock function from being called from layout subviews
        isUpdatingFontSize = true
        
        // Set max and min font sizes
        var currentMaxFontSize = maxFontSize
        var currentMinFontSize = minFontSize
        
        while true
        {
            // Binary search between min and max
            let midFontSize = (currentMaxFontSize + currentMinFontSize) / 2;
            
            // Exit if approached minFontSize enough
            if (midFontSize - currentMinFontSize <= marginOFError)
            {
                // Set min font size and exit because we reached
                // the biggest font size that fits
                currentFont = UIFont(name: currentFont.fontName,
                                     size: currentMinFontSize)!
                
                break;
            }
            else
            {
                // Set the current font size to the midpoint
                currentFont = UIFont(name: currentFont.fontName,
                                     size: midFontSize)!
            }
            
            // Configure an attributed string which can be used to find an
            // appropriate rectangle for a font size using its boundingRect
            // function
            let attribute = [NSAttributedString.Key.font: currentFont]
            let attributedString = NSAttributedString(string: currentText,
                                                      attributes: attribute)
            
            let options: NSStringDrawingOptions = [.usesLineFragmentOrigin,
                                                   .usesFontLeading]
            
            // Get a bounding box with the width of the current label and
            // an unlimited height
            let constrainedSize = CGSize(width: frame.width,
                                         height: CGFloat.greatestFiniteMagnitude)
            
            // Get the appropriate rectangle for the text using the current
            // midpoint font
            let newRect = attributedString.boundingRect(with: constrainedSize,
                                                        options: options,
                                                        context: nil)
            
            // Get the current area of the new rect and the current
            // label's bounds
            let newArea = newRect.width * newRect.height
            let currentArea = bounds.width * bounds.height
            
            // See if the new frame is lesser than the current label's area
            if newArea < currentArea
            {
                // The best font size is in the bigger half
                currentMinFontSize = midFontSize + 1
            }
            else
            {
                // The best font size is in the smaller half
                currentMaxFontSize = midFontSize - 1
            }
        }
        
        // set the font of the current label
        font = currentFont
        
        // Open label to be adjusted again
        isUpdatingFontSize = false
    }
}

here I set sticker view and label:

var testLabel = FlexiFontLabel(frame: CGRect.init(x: 0, y: 0, width: 300, height: 50))
            testLabel.text = "Test Label"
            testLabel.textAlignment = .left
            testLabel.backgroundColor = .blue
            testLabel.adjustsFontForContentSizeCategory = true
            testLabel.numberOfLines = 1
            testLabel.adjustsFontSizeToFitWidth = true
            testLabel.minimumScaleFactor = 0.2
            testLabel.font = testLabel.font.withSize(testLabel.frame.height * 2/3)
            testLabel.doesAdjustFontSizeToFitFrame = true
            
            let stickerView2 = StickerView.init(contentView: testLabel)
            stickerView2.center = CGPoint.init(x: 100, y: 100)
            stickerView2.delegate = self
            stickerView2.setImage(UIImage.init(named: "Close")!, forHandler: StickerViewHandler.close)
            stickerView2.setImage(UIImage.init(named: "Rotate")!, forHandler: StickerViewHandler.rotate)
            stickerView2.showEditingHandlers = false
            self.view.addSubview(stickerView2)

its some how working fine for me but when I change font size of label using slider its size does not change. So my question is how to change font size and stickerview size accordingly. if I change font size using slider label size and stickerview size change accordingly and if I change view width and height its change label font size accordingly.

help will be appreciated thanks.

0 Answers0