大胆&单个UILabel中的非大胆文本?

时间:2010-08-27 17:52:43

标签: ios objective-c swift uilabel nsattributedstring

如何在uiLabel中包含粗体和非粗体文本?

我宁愿不使用UIWebView ..我也读过这可能是使用NSAttributedString,但我不知道如何使用它。有什么想法吗?

Apple在他们的几个应用程序中实现了这一点; 示例屏幕截图:link text

谢谢! - Dom

14 个答案:

答案 0 :(得分:346)

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()

奖金:国际化

有些人对国际化发表了评论。我个人认为这超出了这个问题的范围,但出于教学目的,我就是这样做的

// 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<Int> 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可用)

enter image description here

enter image description here


iOS6及更高版本的先前答案(Objective-C仍有效):

在iOS6 UILabelUIButtonUITextViewUITextField中,支持归因字符串,这意味着我们无需创建CATextLayer作为我们的收件人对于属性字符串。此外,为了生成属性字符串,我们不再需要使用CoreText :)我们在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];
}

来自侵入式代码的人员有一些很好的介绍性博客帖子here,可以解释更多使用NSAttributedString的示例,查找“NSAttributedString简介适用于iOS 6“”使用Interface Builder“

的iOS归属字符串

PS:上面的代码它应该可以工作,但它是脑编译的。我希望它足够了:))


iOS5及以下的旧答案

使用带有NSAttributedString的CATextLayer!比2 UILabels更轻,更简单。 (iOS 3.2及以上版本)

实施例

不要忘记添加QuartzCore框架(CALayers需要)和CoreText(属性字符串需要)。

#import <QuartzCore/QuartzCore.h>
#import <CoreText/CoreText.h>

下面的示例将向导航控制器的工具栏添加一个子图层。在iPhone中使用Mail.app。 :)

- (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 / NSMutableAttributedStringCoreText attributes string keys

希望有所帮助

答案 1 :(得分:82)

在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及更早版本中被忽略。

答案 2 :(得分:46)

Interface Builder

中很容易做到

1)在属性检查器中 UILabel 归属

Bold Example Step 1

2)选择要制作粗体的短语部分

Bold Example Step 2

3)在字体选择器

中更改其字体(或相同字体的粗体字体)

Bold Example Step 3

这就是全部!

答案 3 :(得分:44)

有基于bbrame类别的类别。它的工作原理类似,但允许您使用累积结果多次加粗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 ”。

答案 4 :(得分:25)

它对我有用:

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版本:请参阅Here

答案 5 :(得分:24)

我已经采用了Crazy Yoghurt对快速扩展的回答。

For Each

可能是Range和NSRange之间没有很好的转换,但我没有找到更好的东西。

答案 6 :(得分:20)

结帐TTTAttributedLabel。它是UILabel的直接替代品,允许您通过将NSAttributedString设置为该标签的文本,在单个标签中混合使用字体和颜色。

答案 7 :(得分:11)

在这种情况下你可以尝试,

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, e.g. 2012/10/14*/];
[notifyingStr endEditing];

displayLabel.attributedText = notifyingStr; // or [displayLabel setAttributedText: notifyingStr];

答案 8 :(得分:7)

在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;

答案 9 :(得分:4)

使用以下代码。我希望对你有帮助。

NSString *needToChangeStr=@"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)];

答案 10 :(得分:2)

希望这个能满足您的需求。提供要处理的字符串作为输入,并提供应为粗体/彩色作为输入的单词。

<html lang="en">
<head>
<meta charset="utf-8">
<title>Header</title>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="<?php echo base_url('assert/css/style.css');?>">
    <link rel="stylesheet" href="<?php echo base_url('assert/css/bootstap.css');?>">

</head>
<body>

谢谢。快乐的编码。

答案 11 :(得分:2)

斯威夫特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)")

答案 12 :(得分:1)

我需要在我的项目中实现以下代码(在Swift中)不需要NSRange:

    //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

答案 13 :(得分:0)

如果您想更轻松地使用属性字符串,请尝试使用Attributed String Creator,它将为您生成代码。 https://itunes.apple.com/us/app/attributed-string-creator/id730928349