UIlabel में टेक्स्ट को रेखांकित करें


89

मैं एक पाठ को कैसे रेखांकित कर सकता हूं जो स्ट्रिंग की कई लाइनें हो सकता है? मुझे लगता है कि कुछ लोग UIWebView का सुझाव देते हैं, लेकिन यह स्पष्ट रूप से सिर्फ पाठ रेंडरिंग के लिए एक वर्ग है।

मेरा विचार प्रत्येक पंक्ति में प्रत्येक स्ट्रिंग के प्रारंभ बिंदु और लंबाई का पता लगाना था। और उसके अनुसार एक लाइन ड्रा करें।

मैं समस्याओं का सामना करता हूं कि कैसे लंबाई का पता लगाया जाए और स्ट्रिंग के लिए बिंदु शुरू किया जाए।

मैंने उपयोग करने की कोशिश की -[UILabel textRectForBounds:limitedToNumberOfLines:], यह पाठ के लिए ड्राइंग बाउंडिंग राईट होना चाहिए? फिर मुझे संरेखण पर काम करना होगा? जब मैं केंद्र-औचित्यपूर्ण और सही-सही हो, तो मुझे प्रत्येक पंक्ति का प्रारंभ बिंदु कैसे मिल सकता है?


जवाबों:


137

आप यूआईबेल से उप-वर्ग कर सकते हैं और ड्राअरक्ट विधि को ओवरराइड कर सकते हैं:

- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetRGBStrokeColor(ctx, 207.0f/255.0f, 91.0f/255.0f, 44.0f/255.0f, 1.0f); // RGBA
    CGContextSetLineWidth(ctx, 1.0f);

    CGContextMoveToPoint(ctx, 0, self.bounds.size.height - 1);
    CGContextAddLineToPoint(ctx, self.bounds.size.width, self.bounds.size.height - 1);

    CGContextStrokePath(ctx);

    [super drawRect:rect];  
}

UPD:
iOS 6 के रूप में Apple ने UILabel के लिए NSAttributedString समर्थन जोड़ा, इसलिए अब यह बहुत आसान है और कई लाइनों में काम करता है:

NSDictionary *underlineAttribute = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
myLabel.attributedText = [[NSAttributedString alloc] initWithString:@"Test string" 
                                                         attributes:underlineAttribute];

यदि आप अभी भी iOS 4 और iOS 5 को सपोर्ट करना चाहते हैं, तो मैं मैन्युअल रूप से अंडरलाइन लेबल के बजाय TTTAttributedLabel का उपयोग करने की सलाह दूंगा । हालाँकि, यदि आपको एक-लाइन UILabel को रेखांकित करने की आवश्यकता है और तीसरे पक्ष के घटकों का उपयोग नहीं करना चाहते हैं, तो ऊपर दिए गए कोड अभी भी चाल चलेंगे।


3
मुझे लगता है कि यह केवल स्ट्रिंग की अंतिम पंक्ति के लिए एक अंडरलाइन खींचेगा, है ना? अन्य लाइनों में स्ट्रिंग के लिए अंडरलाइन के बारे में क्या?
सेमीक्स

2
यह कई लाइनें नहीं करता है, लेकिन यह सबसे अच्छा मैं पा सकता हूं, इसलिए मुझे लगता है कि कई लाइनें सवाल से बाहर हैं। मुझे लगता है कि अगले सबसे अच्छा समाधान मुझे लगता है कि एक फ़ॉन्ट आयात करने के लिए है जो कि फ़ॉन्ट में निर्मित एक रेखांकन है। यह केवल ios 4.0+ से काम करेगा जहां आप फोंट आयात कर सकते हैं।
डोनालिया

नमस्ते, मैं जानना चाहता हूं कि क्या यह ios ui मानकों में से किसी का उल्लंघन करता है।
thndrkiss

Apple का कार्यान्वयन (दूसरा सुझाव) उन वर्णों का समर्थन नहीं करता है जो लाइन के नीचे जाते हैं? screencast.com/t/NGvQJqoWAD3J
pfrank

अगर हम G, p & q जैसे वर्णमाला के लिए, UILabel के लिए NSAttributedString समर्थन का उपयोग करते हैं, तो यह कम हो रहा है। कोई भी इस मुद्दे का सामना कर रहा है? उदाहरण: लॉगिन
dev4u

46

स्विफ्ट में:

let underlineAttriString = NSAttributedString(string: "attriString",
                                          attributes: [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue])
label.attributedText = underlineAttriString

केवल एक चीज जो आपको स्विफ्ट 3 में करनी है वह है बदलाव ।StyleSingle to .styleSingle, यह Swift3 में ऊंटनी है, लेकिन बहुत अच्छा जवाब!
जोश ओ'कॉनर

.RawValue के बिना, यह मेरे लिए एक दुर्घटना का कारण बन रहा था।
जैकऑफ़लकोड

आपको केवल आवश्यकता होगी। स्विवल 4.0 के लिए .Value के लिए
carrotzoe

बहुत अस्पष्ट सिर्फ रेखांकित करने के लिए।
khcpietro

38

यह जो मैंने किया है। यह मक्खन की तरह काम करता है।

1) अपने फ्रेमवर्क में CoreText.framework जोड़ें।

2) आयात <CoreText / CoreText.h> उस वर्ग में जहाँ आपको रेखांकित लेबल की आवश्यकता है।

3) निम्नलिखित कोड लिखें।

    NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:@"My Messages"];
    [attString addAttribute:(NSString*)kCTUnderlineStyleAttributeName
              value:[NSNumber numberWithInt:kCTUnderlineStyleSingle]
              range:(NSRange){0,[attString length]}];
    self.myMsgLBL.attributedText = attString;
    self.myMsgLBL.textColor = [UIColor whiteColor];

इस जवाब के लिए मेरे से +1, क्योंकि यह वास्तव में शानदार ढंग से काम करता है, और यह एक विशिष्ट चरित्र श्रेणी के रूप में अच्छी तरह से सेट करने के लिए एक आसान तरीका दर्शाता है (जो कि मुझे खुद की आवश्यकता थी)। धन्यवाद! - एरिक
एरिक वैन डेर नीट

19

एक विशेषता स्ट्रिंग का उपयोग करें:

NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:@"Your String"]
[attrString addAttribute:(NSString*)kCTUnderlineStyleAttributeName 
                   value:[NSNumber numberWithInt:kCTUnderlineStyleSingle] 
                   range:(NSRange){0,[attrString length]}];

और फिर लेबल को ओवरराइड करें - (शून्य) drawTextInRect: (CGRect) aRect और टेक्स्ट को कुछ इस तरह से रेंडर करें:

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrString);
drawingRect = self.bounds;
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, drawingRect);
textFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0), path, NULL);
CGPathRelease(path);
CFRelease(framesetter);
CTFrameDraw(textFrame, ctx);
CGContextRestoreGState(ctx);

या फिर ओवरराइड करने के बजाय अभी तक ऑलिवियर हॉलिगॉन द्वारा बनाए गए OHAttributedLabel का उपयोग करें


1
शीर्ष पंक्ति किया जाना चाहिएNSMutableAttributedString
borrrden

OHAttributedLabel का उपयोग करने के कारण मैं गिरा, वह था - मेरे लिए कम से कम, सटीक पाठ ऊंचाई की गणना करना संभव नहीं था। 10% मामलों में यह गलत था। (शायद इसलिए कि मैं अलग-अलग फॉन्ट का इस्तेमाल कर रहा था ..)
गुंटिस ट्रेन्डैंड्स

15

मैंने कुछ प्रदान किए गए उत्तरों को जोड़ दिया है, बेहतर बनाने के लिए (कम से कम मेरी आवश्यकताओं के लिए), यूबिलब उपवर्ग, जो समर्थन करता है:

  • विभिन्न लेबल सीमाओं के साथ बहुस्तरीय पाठ (पाठ लेबल फ्रेम, या सटीक आकार के बीच में हो सकता है)
  • रेखांकन
  • मिटाना
  • अंडरलाइन / स्ट्राइक लाइन ऑफ़सेट
  • पाठ्य संरेखण
  • विभिन्न फ़ॉन्ट आकार

https://github.com/GuntisTreulands/UnderLineLabel


11

लोग, जो दृश्य (UILabel / UIButton) आदि को उप-वर्ग नहीं करना चाहते हैं ... 'भूल-भुलैया' को किसी भी लाइबल से बदला जा सकता है।

-(void) drawUnderlinedLabel {
    NSString *string = [forgetButton titleForState:UIControlStateNormal];
    CGSize stringSize = [string sizeWithFont:forgetButton.titleLabel.font];
    CGRect buttonFrame = forgetButton.frame;
    CGRect labelFrame = CGRectMake(buttonFrame.origin.x + buttonFrame.size.width - stringSize.width, 
            buttonFrame.origin.y + stringSize.height + 1 , 
            stringSize.width, 2);
    UILabel *lineLabel = [[UILabel alloc] initWithFrame:labelFrame];
    lineLabel.backgroundColor = [UIColor blackColor];
    //[forgetButton addSubview:lineLabel];
    [self.view addSubview:lineLabel];
}

2
-1 को "ड्रा ..." कहने के लिए एक विधि जो एक यूबेल आवंटित करता है और इसे दृश्य में जोड़ता है।
5:14 बजे jcayzac

1
मैंने इसे थोड़ा और सामान्य होने के लिए अनुकूलित किया है: pastebin.com/QkF9ifpb मूल के लिए कोई खाता नहीं है यदि लेबल सबव्यू में है।
फॉनिक्स

8
NSString *tem =self.detailCustomerCRMCaseLabel.text;
if (tem != nil && ![tem isEqualToString:@""]) {
    NSMutableAttributedString *temString=[[NSMutableAttributedString alloc]initWithString:tem];
    [temString addAttribute:NSUnderlineStyleAttributeName
                      value:[NSNumber numberWithInt:1]
                      range:(NSRange){0,[temString length]}];
    self.detailCustomerCRMCaseLabel.attributedText = temString;
}

7

एक और समाधान हो सकता है (चूंकि iOS 7) ने एक नकारात्मक मूल्य दिया NSBaselineOffsetAttributeName, उदाहरण के लिए आपका NSAttributedStringहो सकता है:

NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:@"my text goes here'
                                                            attributes:@{NSFontAttributeName: [UIFont fontWithName:@"Helvetica-Regular" size:12],
                                                                         NSForegroundColorAttributeName: [UIColor blackColor],
                                                                         NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle), NSBaselineOffsetAttributeName: @(-3)}];

आशा है कि यह मदद करेगा; ;-)



3

आप नाम रेखांकित के साथ एक कस्टम लेबल बना सकते हैं और drawRect फ़ंक्शन को संपादित कर सकते हैं।

#import "UnderlinedLabel.h"

@implementation UnderlinedLabel

- (void)drawRect:(CGRect)rect
{
   NSString *normalTex = self.text;
   NSDictionary *underlineAttribute = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
   self.attributedText = [[NSAttributedString alloc] initWithString:normalTex
                                                      attributes:underlineAttribute];

   [super drawRect:rect];
}

3

यहां सबसे आसान समाधान है जो अतिरिक्त कोड लिखे बिना मेरे लिए काम करता है।

// To underline text in UILable
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@"Type your text here"];
[text addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(0, text.length)];
lblText.attributedText = text;

3

कभी-कभी हम डेवलपर किसी भी यूआई स्क्रीन के छोटे डिजाइनिंग हिस्से में फंस जाते हैं। सबसे चिड़चिड़ापन आवश्यकता में से एक लाइन पाठ के तहत है। यहाँ चिंता मत करो समाधान है।

यहाँ छवि विवरण दर्ज करें

उद्देश्य C का उपयोग करके एक UILabel में एक पाठ को रेखांकित करना

UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 320, 480)];
label.backgroundColor=[UIColor lightGrayColor];
NSMutableAttributedString *attributedString;
attributedString = [[NSMutableAttributedString alloc] initWithString:@"Apply Underlining"];
[attributedString addAttribute:NSUnderlineStyleAttributeName value:@1 range:NSMakeRange(0,
[attributedString length])];
[label setAttributedText:attributedString];

स्विफ्ट का उपयोग करके यूआईबेल में एक पाठ को रेखांकित करना

 label.backgroundColor = .lightGray
 let attributedString = NSMutableAttributedString.init(string: "Apply UnderLining")
 attributedString.addAttribute(NSUnderlineStyleAttributeName, value: 1, range:
NSRange.init(location: 0, length: attributedString.length))
 label.attributedText = attributedString

1

कोडपा (रंग और रेखा आकार) के कोड का एक बढ़ाया संस्करण

@implementation UILabelUnderlined

- (void)drawRect:(CGRect)rect {

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    const CGFloat* colors = CGColorGetComponents(self.textColor.CGColor);

    CGContextSetRGBStrokeColor(ctx, colors[0], colors[1], colors[2], 1.0); // RGBA

    CGContextSetLineWidth(ctx, 1.0f);

    CGSize tmpSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(200, 9999)];

    CGContextMoveToPoint(ctx, 0, self.bounds.size.height - 1);
    CGContextAddLineToPoint(ctx, tmpSize.width, self.bounds.size.height - 1);

    CGContextStrokePath(ctx);

    [super drawRect:rect];  
}

@end

1

मैंने मल्टीलाइन uilabel को अंडरलाइन के साथ बनाया है:

फॉन्ट साइज के लिए 8 से 13 सेट इंट लाइनहाइट = self.font.pointSize + 3;

फ़ॉन्ट आकार के लिए 14 से 20 सेट इंट लाइनहाइट = self.font.pointSize + 4;

- (void)drawRect:(CGRect)rect 

{

CGContextRef ctx = UIGraphicsGetCurrentContext();

const CGFloat* colors = CGColorGetComponents(self.textColor.CGColor);

CGContextSetRGBStrokeColor(ctx, colors[0], colors[1], colors[2], 1.0); // RGBA

CGContextSetLineWidth(ctx, 1.0f);
CGSize tmpSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(self.frame.size.width, 9999)];

int height = tmpSize.height;

int lineHeight = self.font.pointSize+4;    

int maxCount = height/lineHeight;

float totalWidth = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(1000, 9999)].width;

for(int i=1;i<=maxCount;i++)

{

    float width=0.0;
    if((i*self.frame.size.width-totalWidth)<=0)
        width = self.frame.size.width;
    else
        width = self.frame.size.width - (i* self.frame.size.width - totalWidth);
    CGContextMoveToPoint(ctx, 0, lineHeight*i-1);
    CGContextAddLineToPoint(ctx, width, lineHeight*i-1);
}

CGContextStrokePath(ctx);

[super drawRect:rect]; 
}

0

जैसा कि कोवपस ने दिखाया है कि आप ज्यादातर मामलों में बाउंडिंग बॉक्स का उपयोग कर सकते हैं, हालांकि यह हमेशा गारंटी नहीं है कि पाठ के चारों ओर बाउंडिंग बॉक्स बड़े करीने से फिट होगा। 50 की ऊंचाई और 12 के फ़ॉन्ट आकार के साथ एक बॉक्स आपको यूआईबेल कॉन्फ़िगरेशन के आधार पर वांछित परिणाम नहीं दे सकता है।

अपने सटीक मेट्रिक्स को निर्धारित करने के लिए यूआईलैब के भीतर UIString को क्वेरी करें और इनका उपयोग कोलाइन द्वारा पहले से उपलब्ध आरेखण कोड का उपयोग करते हुए एन्कोडिंग बाउंडिंग बॉक्स या फ्रेम की परवाह किए बिना बेहतर तरीके से करें।

आपको UIFont की "अग्रणी" संपत्ति को भी देखना चाहिए जो किसी विशेष फ़ॉन्ट के आधार पर आधार रेखा के बीच की दूरी देता है। आधार रेखा वह जगह है जहाँ आप चाहते हैं कि आपकी रेखांकित रेखा खींची जाए।

NSString के लिए UIKit परिवर्धन देखें:

(CGSize)sizeWithFont:(UIFont *)font 
//Returns the size of the string if it were to be rendered with the specified font on a single line.

(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size 
// Returns the size of the string if it were rendered and constrained to the specified size.

(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode
//Returns the size of the string if it were rendered with the specified constraints.

केनी ऐसा लगता है कि मैं पाठ की पहली पंक्ति की चौड़ाई को आसानी से प्राप्त करने के लिए 3 विधियों का उपयोग कर सकता हूं, लेकिन 2 डी 3 और अन्य लाइनों के बारे में कैसे? क्या आप एक उदाहरण दे सकते हैं?
semix

मुझे मानना ​​पड़ेगा। अब NSString का उपयोग करने का एक तरीका है जो आप चाहते हैं, जब तक कि किसी और के पास प्रस्ताव न हो। मुझे UIWebView का उपयोग करने और अपने पाठ को देखने के लिए मेरे सामने दूसरों की तरह सुझाव देने के लिए जाना जा रहा है: [webView loadHTMLString: @ "<html> <u> रेखांकित पाठ। </ u> </ html>" आधारभूत: nil। ]; यह लेआउट और निर्धारण करते हैं कि लाइनें कहाँ जानी चाहिए। यदि यह आप का मामला है, तो nth लाइन को रेखांकित किया जाना चाहिए और आप यह नहीं जान सकते कि कौन सी nth लाइन है, यह एक और मामला है।
गनाशर

0

मैं एक ओपन सोर्स लाइन व्यू का उपयोग करता हूं और बस इसे बटन सबव्यू में जोड़ा है:

 UILabel *label = termsButton.titleLabel;
 CGRect frame = label.frame;
 frame.origin.y += frame.size.height - 1;
 frame.size.height = 1;
 SSLineView *line = [[SSLineView alloc] initWithFrame:frame];
 line.lineColor = [UIColor lightGrayColor];
 [termsButton addSubview:line];

यह ऊपर करीम से प्रेरित था।


आप बस UIVIew का उपयोग कर सकते हैं। यूइवीवाई * लाइन = [[यूआईवाईयूवी आवंटन] initWithFrame: फ्रेम]; line.backgroundColor = [UIColor lightGrayColor];
dzeikei

0

कोवपस और डेमियन प्राका के उत्तरों के आधार पर, यहां UILabelUnderligned का कार्यान्वयन है जो textAlignemnt का भी समर्थन करता है

#import <UIKit/UIKit.h>

@interface UILabelUnderlined : UILabel

@end

और कार्यान्वयन:

#import "UILabelUnderlined.h"

@implementation DKUILabel

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)drawRect:(CGRect)rect {

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    const CGFloat* colors = CGColorGetComponents(self.textColor.CGColor);

    CGContextSetRGBStrokeColor(ctx, colors[0], colors[1], colors[2], 1.0); // RGBA

    CGContextSetLineWidth(ctx, 1.0f);

    CGSize textSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(200, 9999)];

    // handle textAlignement

    int alignementXOffset = 0;

    switch (self.textAlignment) {
        case UITextAlignmentLeft:
            break;
        case UITextAlignmentCenter:
            alignementXOffset = (self.frame.size.width - textSize.width)/2;
            break;
        case UITextAlignmentRight:
            alignementXOffset = self.frame.size.width - textSize.width;
            break;
    }

    CGContextMoveToPoint(ctx, alignementXOffset, self.bounds.size.height - 1);
    CGContextAddLineToPoint(ctx, alignementXOffset+textSize.width, self.bounds.size.height - 1);

    CGContextStrokePath(ctx);

    [super drawRect:rect];  
}


@end

स्विच के लिए iOS 6 के लिए अपडेट: स्विच (self.textAlignment) {केस NSTextAlignmentLeft: मामला NSTextAlignmentJustified: case NSTextAlignmentNatural: break; मामला NSTextAlignmentCenter: alignementXOffset = (self.titleLabel.frame.size. उपलब्धता - textSize. उपलब्धता) / 2; टूटना; मामला NSTextAlignmentRight: alignementXOffset = self.titleLabel.frame.size. उपलब्धता - textSize. उपलब्धता; टूटना; }
pfrank

0

यहां एक और सरल उपाय है (अंडरलाइन की चौड़ाई सबसे सटीक नहीं है लेकिन यह मेरे लिए काफी अच्छा था)

मेरे पास एक UIView (_view_underline)है जिसमें व्हाइट बैकग्राउंड है, 1 पिक्सेल की ऊंचाई है और मैं इसकी चौड़ाई को हर बार अपडेट करता हूं जब मैं टेक्स्ट अपडेट करता हूं

// It's a shame you have to do custom stuff to underline text
- (void) underline  {
    float width = [[_txt_title text] length] * 10.0f;
    CGRect prev_frame = [_view_underline frame];
    prev_frame.size.width = width;
    [_view_underline setFrame:prev_frame];
}

0

NSUnderlineStyleAttributeName जो एक NSNumber (जहाँ 0 कोई रेखांकन नहीं है) को एक विशेषता शब्दकोश में जोड़ा जा सकता है। मुझे नहीं पता कि क्या यह कोई आसान है। लेकिन, यह मेरे उद्देश्यों के लिए आसान था।

    NSDictionary *attributes; 
    attributes = @{NSFontAttributeName:font,   NSParagraphStyleAttributeName: style, NSUnderlineStyleAttributeName:[NSNumber numberWithInteger:1]};

    [text drawInRect:CGRectMake(self.contentRect.origin.x, currentY, maximumSize.width, textRect.size.height) withAttributes:attributes];

0

स्विफ्ट 4.1 वर:

 let underlineAttriString = NSAttributedString(string:"attriString", attributes:
    [NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue])

label.attributedText = underlineAttriString

0

आप मेरे इस कस्टम लेबल का उपयोग कर सकते हैं! आप सेट करने के लिए इंटरफ़ेस बिल्डर का उपयोग भी कर सकते हैं

import UIKit


class  YHYAttributedLabel : UILabel{
    
    
    @IBInspectable
    var underlineText : String = ""{
        
        didSet{

            self.attributedText = NSAttributedString(string: underlineText,
            attributes: [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue])
        }
        
        
    }

}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.