Полужирный и нежирный текст в одном UILabel?

Как можно было бы включить как полужирный, так и нежирный текст в uiLabel?

Я бы предпочел не использовать UIWebView. Я также читал, что это может быть возможно с помощью NSAttributedString, но я понятия не имею, как это использовать. Есть идеи?

Apple добивается этого в нескольких своих приложениях; Примеры Скриншот: текст ссылки

Благодаря! – Дом

Обновление для Swift3

В Swift нам не нужно иметь дело с старым материалом iOS5, кроме того, синтаксис короче, поэтому все становится очень простым:

func attributedString(from string: String, nonBoldRange: NSRange?) -> NSAttributedString { let fontSize = UIFont.systemFontSize let attrs = [ NSFontAttributeName: UIFont.boldSystemFont(ofSize: fontSize), NSForegroundColorAttributeName: UIColor.black ] let nonBoldAttribute = [ NSFontAttributeName: UIFont.systemFont(ofSize: fontSize), ] let attrStr = NSMutableAttributedString(string: string, attributes: attrs) if let range = nonBoldRange { attrStr.setAttributes(nonBoldAttribute, range: range) } return attrStr } 

Применение:

 let targetString = "Updated 2012/10/14 21:59 PM" let range = NSMakeRange(7, 12) let label = UILabel(frame: CGRect(x:0, y:0, width:350, height:44)) label.backgroundColor = UIColor.white label.attributedText = attributedString(from: targetString, nonBoldRange: range) label.sizeToFit() 

Бонус: интернационализация

Некоторые люди прокомментировали интернационализацию. Я лично считаю, что это выходит за frameworks этого вопроса, но для учебных целей это то, как я это сделал бы

 // Date we want to show let date = Date() // Create the string. // I don't set the locale because the default locale of the formatter is `NSLocale.current` so it's good for internationalisation :p let formatter = DateFormatter() formatter.dateStyle = .medium formatter.timeStyle = .short let targetString = String(format: NSLocalizedString("Update %@", comment: "Updated string format"), formatter.string(from: date)) // Find the range of the non-bold part formatter.timeStyle = .none let nonBoldRange = targetString.range(of: formatter.string(from: date)) // Convert Range into NSRange let nonBoldNSRange: NSRange? = nonBoldRange == nil ? nil : NSMakeRange(targetString.distance(from: targetString.startIndex, to: nonBoldRange!.lowerBound), targetString.distance(from: nonBoldRange!.lowerBound, to: nonBoldRange!.upperBound)) // Now just build the attributed string as before :) label.attributedText = attributedString(from: targetString, nonBoldRange: nonBoldNSRange) 

Результат (Предположим, что доступны английский и японский Localizable.strings)

введите описание изображения здесь

введите описание изображения здесь


Предыдущий ответ для iOS6 и более поздних версий (Objective-C все еще работает):

В iOS6 UILabel , UIButton , UITextView , UITextField , поддерживаются атрибутные строки, что означает, что нам не нужно создавать CATextLayer s в качестве получателя для атрибутированных строк. Кроме того, чтобы сделать атрибутивную строку, нам больше не нужно играть с CoreText 🙂 У нас есть новые classы в obj-c Foundation.framework, такие как NSParagraphStyle и другие константы, которые облегчат нашу жизнь. Ура!

Итак, если у нас есть эта строка:

 NSString *text = @"Updated: 2012/10/14 21:59" 

Нам нужно создать только атрибутную строку:

 if ([_label respondsToSelector:@selector(setAttributedText:)]) { // iOS6 and above : Use NSAttributedStrings // Create the attributes const CGFloat fontSize = 13; NSDictionary *attrs = @{ NSFontAttributeName:[UIFont boldSystemFontOfSize:fontSize], NSForegroundColorAttributeName:[UIColor whiteColor] }; NSDictionary *subAttrs = @{ NSFontAttributeName:[UIFont systemFontOfSize:fontSize] }; // Range of " 2012/10/14 " is (8,12). Ideally it shouldn't be hardcoded // This example is about attributed strings in one label // not about internationalisation, so we keep it simple :) // For internationalisation example see above code in swift const NSRange range = NSMakeRange(8,12); // Create the attributed string (text + attributes) NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:text attributes:attrs]; [attributedText setAttributes:subAttrs range:range]; // Set it in our UILabel and we are done! [_label setAttributedText:attributedText]; } else { // iOS5 and below // Here we have some options too. The first one is to do something // less fancy and show it just as plain text without attributes. // The second is to use CoreText and get similar results with a bit // more of code. Interested people please look down the old answer. // Now I am just being lazy so :p [_label setText:text]; } 

Существует пара хороших вступительных сообщений в блогах от ребята из invasivecode, которые объясняют больше примеров использования NSAttributedString , ищите «Введение в NSAttributedString для iOS 6» и «Атрибутивные строки для iOS с помощью Interface Builder» 🙂

PS: Над кодом он должен работать, но он был скомпилирован мозгом. Надеюсь, этого достаточно 🙂


Старый ответ для iOS5 и ниже

Используйте CATextLayer с NSAttributedString! намного легче и проще, чем 2 UILabels. (iOS 3.2 и выше)

Пример.

Не забудьте добавить фреймворк QuartzCore (необходимый для CALayers) и CoreText (необходимый для атрибутной строки).

 #import  #import  

Ниже приведен пример подуровня панели инструментов навигационного controllerа. à la Mail.app в iPhone. 🙂

 - (void)setRefreshDate:(NSDate *)aDate { [aDate retain]; [refreshDate release]; refreshDate = aDate; if (refreshDate) { /* Create the text for the text layer*/ NSDateFormatter *df = [[NSDateFormatter alloc] init]; [df setDateFormat:@"MM/dd/yyyy hh:mm"]; NSString *dateString = [df stringFromDate:refreshDate]; NSString *prefix = NSLocalizedString(@"Updated", nil); NSString *text = [NSString stringWithFormat:@"%@: %@",prefix, dateString]; [df release]; /* Create the text layer on demand */ if (!_textLayer) { _textLayer = [[CATextLayer alloc] init]; //_textLayer.font = [UIFont boldSystemFontOfSize:13].fontName; // not needed since `string` property will be an NSAttributedString _textLayer.backgroundColor = [UIColor clearColor].CGColor; _textLayer.wrapped = NO; CALayer *layer = self.navigationController.toolbar.layer; //self is a view controller contained by a navigation controller _textLayer.frame = CGRectMake((layer.bounds.size.width-180)/2 + 10, (layer.bounds.size.height-30)/2 + 10, 180, 30); _textLayer.contentsScale = [[UIScreen mainScreen] scale]; // looks nice in retina displays too :) _textLayer.alignmentMode = kCAAlignmentCenter; [layer addSublayer:_textLayer]; } /* Create the attributes (for the attributed string) */ CGFloat fontSize = 13; UIFont *boldFont = [UIFont boldSystemFontOfSize:fontSize]; CTFontRef ctBoldFont = CTFontCreateWithName((CFStringRef)boldFont.fontName, boldFont.pointSize, NULL); UIFont *font = [UIFont systemFontOfSize:13]; CTFontRef ctFont = CTFontCreateWithName((CFStringRef)font.fontName, font.pointSize, NULL); CGColorRef cgColor = [UIColor whiteColor].CGColor; NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: (id)ctBoldFont, (id)kCTFontAttributeName, cgColor, (id)kCTForegroundColorAttributeName, nil]; CFRelease(ctBoldFont); NSDictionary *subAttributes = [NSDictionary dictionaryWithObjectsAndKeys:(id)ctFont, (id)kCTFontAttributeName, nil]; CFRelease(ctFont); /* Create the attributed string (text + attributes) */ NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes]; [attrStr addAttributes:subAttributes range:NSMakeRange(prefix.length, 12)]; //12 is the length of " MM/dd/yyyy/ " /* Set the attributes string in the text layer :) */ _textLayer.string = attrStr; [attrStr release]; _textLayer.opacity = 1.0; } else { _textLayer.opacity = 0.0; _textLayer.string = nil; } } 

В этом примере у меня есть только два разных типа шрифта (жирный и обычный), но вы также можете иметь разные размеры шрифта, разные цвета, курсив, подчеркнутый и т. Д. Посмотрите на строковые ключи NSAttributedString / NSMutableAttributedString и CoreText .

Надеюсь, поможет

Попробуйте категорию на UILabel:

Вот как он используется:

 myLabel.text = @"Updated: 2012/10/14 21:59 PM"; [myLabel boldSubstring: @"Updated:"]; [myLabel boldSubstring: @"21:59 PM"]; 

И вот категория

UILabel + Boldify.h

 - (void) boldSubstring: (NSString*) substring; - (void) boldRange: (NSRange) range; 

UILabel + Boldify.m

 - (void) boldRange: (NSRange) range { if (![self respondsToSelector:@selector(setAttributedText:)]) { return; } NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText]; [attributedText setAttributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:self.font.pointSize]} range:range]; self.attributedText = attributedText; } - (void) boldSubstring: (NSString*) substring { NSRange range = [self.text rangeOfString:substring]; [self boldRange:range]; } 

Обратите внимание, что это будет работать только в iOS 6 и более поздних версиях. Он будет просто проигнорирован в iOS 5 и ранее.

Есть категория, основанная на категории bbrame. Он работает аналогично, но позволяет вам одновременно UILabel один и UILabel же UILabel с кумулятивными результатами.

UILabel + Boldify.h

 @interface UILabel (Boldify) - (void) boldSubstring: (NSString*) substring; - (void) boldRange: (NSRange) range; @end 

UILabel + Boldify.m

 @implementation UILabel (Boldify) - (void)boldRange:(NSRange)range { if (![self respondsToSelector:@selector(setAttributedText:)]) { return; } NSMutableAttributedString *attributedText; if (!self.attributedText) { attributedText = [[NSMutableAttributedString alloc] initWithString:self.text]; } else { attributedText = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText]; } [attributedText setAttributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:self.font.pointSize]} range:range]; self.attributedText = attributedText; } - (void)boldSubstring:(NSString*)substring { NSRange range = [self.text rangeOfString:substring]; [self boldRange:range]; } @end 

С помощью этих исправлений вы можете использовать его несколько раз, например:

 myLabel.text = @"Updated: 2012/10/14 21:59 PM"; [myLabel boldSubstring: @"Updated:"]; [myLabel boldSubstring: @"21:59 PM"]; 

приведет к: « Обновлено: 2012/10/14 21:59 PM ».

Это легко сделать в Interface Builder :

1) сделать UILabel Attributed in Attributes Inspector

Полужирный Пример Шаг 1

2) выберите часть фразы, которую вы хотите сделать полужирным

Полужирный Пример 2

3) изменить шрифт (или полужирный шрифт того же шрифта) в селекторе шрифта

Полужирный Пример Шаг 3

Это все!

Это сработало для меня:

 CGFloat boldTextFontSize = 17.0f; myLabel.text = [NSString stringWithFormat:@"%@ 2012/10/14 %@",@"Updated:",@"21:59 PM"]; NSRange range1 = [myLabel.text rangeOfString:@"Updated:"]; NSRange range2 = [myLabel.text rangeOfString:@"21:59 PM"]; NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:myLabel.text]; [attributedText setAttributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:boldTextFontSize]} range:range1]; [attributedText setAttributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:boldTextFontSize]} range:range2]; myLabel.attributedText = attributedText; 

Для версии Swift: см. Здесь

Я принял ответ Crazy Yoghurt на продление Swift.

 extension UILabel { func boldRange(_ range: Range) { if let text = self.attributedText { let attr = NSMutableAttributedString(attributedString: text) let start = text.string.characters.distance(from: text.string.startIndex, to: range.lowerBound) let length = text.string.characters.distance(from: range.lowerBound, to: range.upperBound) attr.addAttributes([NSFontAttributeName: UIFont.boldSystemFont(ofSize: self.font.pointSize)], range: NSMakeRange(start, length)) self.attributedText = attr } } func boldSubstring(_ substr: String) { if let text = self.attributedText { var range = text.string.range(of: substr) let attr = NSMutableAttributedString(attributedString: text) while range != nil { let start = text.string.characters.distance(from: text.string.startIndex, to: range!.lowerBound) let length = text.string.characters.distance(from: range!.lowerBound, to: range!.upperBound) var nsRange = NSMakeRange(start, length) let font = attr.attribute(NSFontAttributeName, at: start, effectiveRange: &nsRange) as! UIFont if !font.fontDescriptor.symbolicTraits.contains(.traitBold) { break } range = text.string.range(of: substr, options: NSString.CompareOptions.literal, range: range!.upperBound.. 

Может быть, нет хорошего преобразования между Range и NSRange, но я не нашел лучшего.

Проверьте TTTAttributedLabel . Это замена для UILabel, которая позволяет вам смешивать шрифт и цвета в одной метке, устанавливая NSAttributedString в качестве текста для этой метки.

В этом случае вы можете попробовать,

 UILabel *displayLabel = [[UILabel alloc] initWithFrame:/*label frame*/]; displayLabel.font = [UIFont boldSystemFontOfSize:/*bold font size*/]; NSMutableAttributedString *notifyingStr = [[NSMutableAttributedString alloc] initWithString:@"Updated: 2012/10/14 21:59 PM"]; [notifyingStr beginEditing]; [notifyingStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:/*normal font size*/] range:NSMakeRange(8,10)/*range of normal string, eg 2012/10/14*/]; [notifyingStr endEditing]; displayLabel.attributedText = notifyingStr; // or [displayLabel setAttributedText: notifyingStr]; 

Сделать текст полужирным, а также подчеркнуть в UILabel. Просто добавьте следующие строки в свой код.

 NSRange range1 = [lblTermsAndCondition.text rangeOfString:NSLocalizedString(@"bold_terms", @"")]; NSRange range2 = [lblTermsAndCondition.text rangeOfString:NSLocalizedString(@"bold_policy", @"")]; NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:lblTermsAndCondition.text]; [attributedText setAttributes:@{NSFontAttributeName:[UIFont fontWithName:fontBold size:12.0]} range:range1]; [attributedText setAttributes:@{NSFontAttributeName:[UIFont fontWithName:fontBold size:12.0]} range:range2]; [attributedText addAttribute:(NSString*)kCTUnderlineStyleAttributeName value:[NSNumber numberWithInt:kCTUnderlineStyleSingle] range:range1]; [attributedText addAttribute:(NSString*)kCTUnderlineStyleAttributeName value:[NSNumber numberWithInt:kCTUnderlineStyleSingle] range:range2]; lblTermsAndCondition.attributedText = attributedText; 

Используйте приведенный ниже код. Надеюсь, это поможет вам.

 NSString *[email protected]"BOOK"; NSString *display_string=[NSString stringWithFormat:@"This is %@",book]; NSMutableAttributedString *attri_str=[[NSMutableAttributedString alloc]initWithString:display_string]; int begin=[display_string length]-[needToChangeStr length]; int end=[needToChangeStr length]; [attri_str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue-Bold" size:30] range:NSMakeRange(begin, end)]; 

Надеюсь, этот будет отвечать вашим потребностям. Поставьте строку для обработки в качестве входных данных и поставьте слова, которые должны быть выделены жирным шрифтом / цветом в качестве входных данных.

 func attributedString(parentString:String, arrayOfStringToProcess:[String], color:UIColor) -> NSAttributedString { let parentAttributedString = NSMutableAttributedString(string:parentString, attributes:nil) let parentStringWords = parentAttributedString.string.components(separatedBy: " ") if parentStringWords.count != 0 { let wordSearchArray = arrayOfStringToProcess.filter { inputArrayIndex in parentStringWords.contains(where: { $0 == inputArrayIndex } )} for eachWord in wordSearchArray { parentString.enumerateSubstrings(in: parentString.startIndex.. 

Спасибо. Счастливое кодирование.

Нет необходимости в NSRange со следующим кодом, который я только что реализовал в своем проекте (в Swift):

  //Code sets label (yourLabel)'s text to "Tap and hold(BOLD) button to start recording." let boldAttribute = [ //You can add as many attributes as you want here. NSFontAttributeName: UIFont(name: "HelveticaNeue-Bold", size: 18.0)!] let regularAttribute = [ NSFontAttributeName: UIFont(name: "HelveticaNeue-Light", size: 18.0)!] let beginningAttributedString = NSAttributedString(string: "Tap and ", attributes: regularAttribute ) let boldAttributedString = NSAttributedString(string: "hold ", attributes: boldAttribute) let endAttributedString = NSAttributedString(string: "button to start recording.", attributes: regularAttribute ) let fullString = NSMutableAttributedString() fullString.appendAttributedString(beginningAttributedString) fullString.appendAttributedString(boldAttributedString) fullString.appendAttributedString(endAttributedString) yourLabel.attributedText = fullString 

Swift 4:

 // attribute with color red and Bold var attrs1 = [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 20), NSAttributedStringKey.foregroundColor: UIColor.red] // attribute with color black and Non Bold var attrs2 = [NSAttributedStringKey.font: UIFont(name: "Roboto-Regular", size: 20), NSAttributedStringKey.foregroundColor: UIColor.black] var color1 = NSAttributedString(string: "RED", attributes: attrs1) var color2 = NSAttributedString(string: " BLACK", attributes: attrs2) var string = NSMutableAttributedString() string.append(color1) string.append(color2) // print the text with **RED** BLACK print("Final String : \(string)") 

Если вы хотите упростить использование атрибутированных строк, попробуйте использовать Attributed String Creator, который будет генерировать код для вас. https://itunes.apple.com/us/app/attributed-string-creator/id730928349

  • Сохранение UIColor и загрузка из NSUserDefaults
  • Очереди отправки: как узнать, запущены ли они и как их остановить
  • Выбор случайного объекта в NSArray
  • Open Source Cocoa / Cocoa-Touch POP3 / SMTP библиотека?
  • Ошибка AdMob с помощью : непризнанный селектор
  • Как вы вычисляете день года на определенную дату в Objective-C?
  • Как получить размер NSString
  • Почему мой коллега MCSession отключается случайно?
  • Не удалось добавить объекты в NSMutableArray в Objective C
  • Каков наилучший способ перетащить NSMutableArray?
  • Кто-нибудь реализовал API PayPal через собственное приложение для iPhone?
  • Давайте будем гением компьютера.