[Ios] UILabel के गतिशील रूप से बदलते फ़ॉन्ट आकार


Answers

minimumFontSize को आईओएस 6 के साथ बहिष्कृत कर दिया गया है। आप minimumScaleFactor उपयोग कर सकते हैं।

yourLabel.adjustsFontSizeToFitWidth=YES;
yourLabel.minimumScaleFactor=0.5;

लेबल और टेक्स्ट की चौड़ाई के अनुसार यह आपके फ़ॉन्ट आकार का ख्याल रखेगा।

Question

मेरे पास वर्तमान में एक UILabel :

factLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, 280, 100)];
factLabel.text = @"some text some text some text some text";
factLabel.backgroundColor = [UIColor clearColor];
factLabel.lineBreakMode = UILineBreakModeWordWrap;
factLabel.numberOfLines = 10;
[self.view addSubview:factLabel];

मेरे आईओएस एप्लिकेशन के पूरे जीवन में, factLabel को विभिन्न मानों का एक समूह मिलता है। कुछ वाक्यों के साथ, दूसरों को केवल 5 या 6 शब्दों के साथ।

मैं UILabel कैसे स्थापित कर सकता हूं ताकि फ़ॉन्ट आकार बदल जाए ताकि पाठ हमेशा परिभाषित सीमाओं में फिट हो?




स्विफ्ट संस्करण:

textLabel.adjustsFontSizeToFitWidth = true
textLabel.minimumScaleFactor = 0.5



यहां UILabel सबक्लास का भरण कोड है जो एनिमेटेड फ़ॉन्ट आकार परिवर्तन लागू करता है:

@interface SNTextLayer : CATextLayer

@end

@implementation SNTextLayer

- (void)drawInContext:(CGContextRef)ctx {
    // We override this to make text appear at the same vertical positon as in UILabel
    // (otherwise it's shifted tdown)
    CGFloat height = self.bounds.size.height;
    float fontSize = self.fontSize;
    // May need to adjust this somewhat if it's not aligned perfectly in your implementation
    float yDiff = (height-fontSize)/2 - fontSize/10;

    CGContextSaveGState(ctx);
    CGContextTranslateCTM(ctx, 0.0, yDiff);
    [super drawInContext:ctx];
     CGContextRestoreGState(ctx);
}

@end

@interface SNAnimatableLabel ()

@property CATextLayer* textLayer;

@end

@interface SNAnimatableLabel : UILabel

- (void)animateFontToSize:(CGFloat)fontSize withDuration:(double)duration;

@end



@implementation SNAnimatableLabel


- (void)awakeFromNib {
    [super awakeFromNib];
    _textLayer = [SNTextLayer new];
    _textLayer.backgroundColor = self.backgroundColor.CGColor;
    _textLayer.foregroundColor = self.textColor.CGColor;
    _textLayer.font = CGFontCreateWithFontName((CFStringRef)self.font.fontName);
    _textLayer.frame = self.bounds;
    _textLayer.string = self.text;
    _textLayer.fontSize = self.font.pointSize;
    _textLayer.contentsScale = [UIScreen mainScreen].scale;
    [_textLayer setPosition: CGPointMake(CGRectGetMidX(_textLayer.frame), CGRectGetMidY(_textLayer.frame))];
    [_textLayer setAnchorPoint: CGPointMake(0.5, 0.5)];
    [_textLayer setAlignmentMode: kCAAlignmentCenter];
    self.textColor = self.backgroundColor;
    // Blend text with background, so that it doens't interfere with textlayer text
    [self.layer addSublayer:_textLayer];
    self.layer.masksToBounds = NO;
}

- (void)setText:(NSString *)text {
    _textLayer.string = text;
    super.text = text;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    // Need to enlarge the frame, otherwise the text may get clipped for bigger font sizes
    _textLayer.frame = CGRectInset(self.bounds, -5, -5);
}

- (void)animateFontToSize:(CGFloat)fontSize withDuration:(double)duration {
    [CATransaction begin];
    [CATransaction setAnimationDuration:duration];
    _textLayer.fontSize = fontSize;
    [CATransaction commit];
}



यह 2015 है। मुझे एक ब्लॉग पोस्ट खोजने के लिए जाना था जो स्विफ्ट के साथ आईओएस और एक्सकोड के नवीनतम संस्करण के लिए इसे कैसे करना है, ताकि यह कई लाइनों के साथ काम करे।

  1. "ऑटोश्रिंक" को "न्यूनतम फ़ॉन्ट आकार" पर सेट करें।
  2. फ़ॉन्ट को सबसे बड़े वांछित फ़ॉन्ट आकार में सेट करें (मैंने 20 चुना है)
  3. "वर्ड लपेटें" से "लाइन ब्रेक" को "टर्न टर्न" में बदलें।

स्रोत: http://beckyhansmeyer.com/2015/04/09/autoshrinking-text-in-a-multiline-uilabel/




यह समाधान multiline के लिए काम करता है:

कई लेखों का पालन करने के बाद, और एक फ़ंक्शन की आवश्यकता होती है जो स्वचालित रूप से टेक्स्ट को स्केल करेगी और लाइन लेबल के भीतर लाइन फिट को समायोजित करेगी, मैंने स्वयं एक फ़ंक्शन लिखा था। (यानी एक छोटी स्ट्रिंग अच्छी तरह से एक लाइन पर फिट होगी और लेबल फ्रेम की एक बड़ी मात्रा का उपयोग करेगी, जबकि एक लंबा मजबूत स्वचालित रूप से 2 या 3 लाइनों पर विभाजित होगा और तदनुसार आकार समायोजित करेगा)

इसे फिर से उपयोग करने के लिए स्वतंत्र महसूस करें और आवश्यकतानुसार ट्विक करें। सुनिश्चित करें कि आप इसे देखने के बाद कॉल करते हैं viewDidLayoutSubviews समाप्त हो गया है ताकि प्रारंभिक लेबल फ्रेम सेट किया गया हो।

+ (void)setFontForLabel:(UILabel *)label withMaximumFontSize:(float)maxFontSize andMaximumLines:(int)maxLines {
    int numLines = 1;
    float fontSize = maxFontSize;
    CGSize textSize; // The size of the text
    CGSize frameSize; // The size of the frame of the label
    CGSize unrestrictedFrameSize; // The size the text would be if it were not restricted by the label height
    CGRect originalLabelFrame = label.frame;

    frameSize = label.frame.size;
    textSize = [label.text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize: fontSize]}];

    // Work out the number of lines that will need to fit the text in snug
    while (((textSize.width / numLines) / (textSize.height * numLines) > frameSize.width / frameSize.height) && (numLines < maxLines)) {
        numLines++;
    }

    label.numberOfLines = numLines;

    // Get the current text size
    label.font = [UIFont systemFontOfSize:fontSize];
    textSize = [label.text boundingRectWithSize:CGSizeMake(frameSize.width, CGFLOAT_MAX)
                                        options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                     attributes:@{NSFontAttributeName : label.font}
                                        context:nil].size;

    // Adjust the frame size so that it can fit text on more lines
    // so that we do not end up with truncated text
    label.frame = CGRectMake(label.frame.origin.x, label.frame.origin.y, label.frame.size.width, label.frame.size.width);

    // Get the size of the text as it would fit into the extended label size
    unrestrictedFrameSize = [label textRectForBounds:CGRectMake(0, 0, label.bounds.size.width, CGFLOAT_MAX) limitedToNumberOfLines:numLines].size;

    // Keep reducing the font size until it fits
    while (textSize.width > unrestrictedFrameSize.width || textSize.height > frameSize.height) {
        fontSize--;
        label.font = [UIFont systemFontOfSize:fontSize];
        textSize = [label.text boundingRectWithSize:CGSizeMake(frameSize.width, CGFLOAT_MAX)
                                            options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                         attributes:@{NSFontAttributeName : label.font}
                                            context:nil].size;
        unrestrictedFrameSize = [label textRectForBounds:CGRectMake(0, 0, label.bounds.size.width, CGFLOAT_MAX) limitedToNumberOfLines:numLines].size;
    }

    // Set the label frame size back to original
    label.frame = originalLabelFrame;
}



यह थोड़ा परिष्कृत नहीं है लेकिन यह काम करना चाहिए, उदाहरण के लिए कहें कि आप अपने यूलाबेल को 120x120 पर कैप करना चाहते हैं, जिसमें 28 का अधिकतम फ़ॉन्ट आकार है:

magicLabel.numberOfLines = 0;
magicLabel.lineBreakMode = NSLineBreakByWordWrapping;
...
magicLabel.text = text;
    for (int i = 28; i>3; i--) {
        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:(CGFloat)i] constrainedToSize:CGSizeMake(120.0f, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];
        if (size.height < 120) {
            magicLabel.font = [UIFont systemFontOfSize:(CGFloat)i];
            break;
        }
    }