Bagaimana saya bisa menggarisbawahi teks yang bisa terdiri dari beberapa baris string? Saya menemukan beberapa orang menyarankan UIWebView, tetapi ini jelas merupakan kelas yang terlalu berat hanya untuk rendering teks.
Pikiranku adalah mencari tahu titik awal dan panjang setiap senar di setiap baris. Dan buat garis di bawahnya sesuai dengan itu.
Saya menemui masalah tentang cara mengetahui panjang dan titik awal untuk string.
Saya mencoba menggunakan -[UILabel textRectForBounds:limitedToNumberOfLines:]
, ini harus menjadi gambar pembatas persegi untuk teks kan? Lalu saya harus mengerjakan perataan? Bagaimana saya bisa mendapatkan titik awal setiap baris jika rata tengah dan rata kanan?
Jawaban:
Anda dapat membuat subkelas dari UILabel dan mengganti metode drawRect:
- (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:
Mulai iOS 6 Apple menambahkan dukungan NSAttributedString untuk UILabel, jadi sekarang jauh lebih mudah dan berfungsi untuk banyak baris:
NSDictionary *underlineAttribute = @{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)}; myLabel.attributedText = [[NSAttributedString alloc] initWithString:@"Test string" attributes:underlineAttribute];
Jika Anda masih ingin mendukung iOS 4 dan iOS 5, saya sarankan untuk menggunakan TTTAttributedLabel daripada label garis bawah secara manual. Namun jika Anda perlu menggarisbawahi satu baris UILabel dan tidak ingin menggunakan komponen pihak ketiga, kode di atas masih bisa digunakan.
sumber
Di Swift:
let underlineAttriString = NSAttributedString(string: "attriString", attributes: [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue]) label.attributedText = underlineAttriString
sumber
Inilah yang saya lakukan. Ini bekerja seperti mentega.
1) Tambahkan CoreText.framework ke Frameworks Anda.
2) impor <CoreText / CoreText.h> di kelas di mana Anda membutuhkan label yang digarisbawahi.
3) Tulis kode berikut.
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];
sumber
Gunakan atribut string:
NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:@"Your String"] [attrString addAttribute:(NSString*)kCTUnderlineStyleAttributeName value:[NSNumber numberWithInt:kCTUnderlineStyleSingle] range:(NSRange){0,[attrString length]}];
Dan kemudian timpa label - (void) drawTextInRect: (CGRect) aRect dan render teks menjadi seperti:
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);
Atau lebih baik lagi daripada menimpa, cukup gunakan OHAttributedLabel yang dibuat oleh Olivier Halligon
sumber
NSMutableAttributedString
Saya telah menggabungkan beberapa jawaban yang diberikan, untuk membuat subkelas UILabel yang lebih baik (setidaknya untuk kebutuhan saya), yang mendukung:
https://github.com/GuntisTreulands/UnderLineLabel
sumber
Orang-orang, yang tidak ingin membuat subclass view (UILabel / UIButton) dll ... 'forgetButton' dapat diganti dengan label apapun juga.
-(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]; }
sumber
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; }
sumber
Solusi lain bisa jadi (karena iOS 7) diberi nilai negatif
NSBaselineOffsetAttributeName
, misalnya AndaNSAttributedString
bisa menjadi:NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:@"my text goes here' attributes:@{NSFontAttributeName: [UIFont fontWithName:@"Helvetica-Regular" size:12], NSForegroundColorAttributeName: [UIColor blackColor], NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle), NSBaselineOffsetAttributeName: @(-3)}];
Semoga ini bisa membantu ;-)
sumber
NSMutableAttributedString *text = [self.myUILabel.attributedText mutableCopy]; [text addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:NSMakeRange(0, text.length)]; self.myUILabel.attributedText = text;
sumber
Anda dapat membuat label khusus dengan nama UnderlinedLabel dan mengedit fungsi 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]; }
sumber
Berikut adalah solusi termudah yang berfungsi untuk saya tanpa menulis kode tambahan.
// 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;
sumber
Terkadang pengembang kami terjebak dalam bagian desain kecil dari layar UI mana pun. Salah satu persyaratan yang paling menjengkelkan adalah di bawah teks baris. Jangan khawatir, inilah solusinya.
Menggarisbawahi teks dalam UILabel menggunakan Objective C
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];
Menggarisbawahi teks dalam UILabel menggunakan Swift
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
sumber
Versi kode Kovpas yang disempurnakan (warna dan ukuran garis)
@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
sumber
Saya telah Membuat untuk uilabel multiline dengan garis bawah:
Untuk Font size 8 sampai 13 set int lineHeight = self.font.pointSize + 3;
Untuk ukuran font 14 sampai 20 set int lineHeight = 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]; }
sumber
Seperti yang ditunjukkan oleh kovpas, Anda dapat menggunakan kotak pembatas dalam banyak kasus, meskipun tidak selalu dijamin bahwa kotak pembatas akan pas dengan rapi di sekitar teks. Sebuah kotak dengan tinggi 50 dan ukuran font 12 mungkin tidak memberikan hasil yang Anda inginkan tergantung pada konfigurasi UILabel.
Buat kueri UIString dalam UILabel untuk menentukan metrik yang tepat dan gunakan ini untuk menempatkan garis bawah Anda dengan lebih baik terlepas dari kotak pembatas atau bingkai yang melingkupi menggunakan kode gambar yang telah disediakan oleh kovpas.
Anda juga harus melihat properti "leading" UIFont yang memberikan jarak antara baseline berdasarkan font tertentu. Garis dasar adalah tempat Anda ingin garis bawah digambar.
Cari tambahan UIKit ke NSString:
(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.
sumber
Saya menggunakan tampilan garis open source dan baru saja menambahkannya ke subview tombol:
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];
Ini terinspirasi dari Karim di atas.
sumber
Berdasarkan Jawaban Kovpas & Damien Praca, berikut adalah implementasi UILabelUnderligned yang juga mendukung textAlignemnt .
#import <UIKit/UIKit.h> @interface UILabelUnderlined : UILabel @end
dan implementasinya:
#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
sumber
Inilah solusi lain yang lebih sederhana (lebar garis bawah tidak paling akurat tetapi cukup baik untuk saya)
Saya memiliki UIView
(_view_underline)
yang memiliki latar belakang Putih, tinggi 1 piksel dan saya memperbarui lebarnya setiap kali saya memperbarui teks// 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]; }
sumber
NSUnderlineStyleAttributeName yang mengambil NSNumber (di mana 0 adalah tanpa garis bawah) dapat ditambahkan ke kamus atribut. Saya tidak tahu apakah ini lebih mudah. Tapi, itu lebih mudah untuk tujuan saya.
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];
sumber
Swift 4.1 ver:
let underlineAttriString = NSAttributedString(string:"attriString", attributes: [NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue]) label.attributedText = underlineAttriString
sumber
Anda dapat menggunakan label khusus saya ini! Anda juga dapat menggunakan pembuat antarmuka untuk mengatur
import UIKit class YHYAttributedLabel : UILabel{ @IBInspectable var underlineText : String = ""{ didSet{ self.attributedText = NSAttributedString(string: underlineText, attributes: [NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue]) } } }
sumber