NSAttributedString вставка маркера? - PullRequest
24 голосов
/ 11 июля 2011

Итак, у меня есть NSAttributedString Я хочу вставить bullet point в начале части текста. Как я могу это сделать? Как создать CTPAragraphStyle, который создает эту точку маркера при отображении текста?

Edit: Должно быть доступно на iOS

Ответы [ 6 ]

34 голосов
/ 11 июля 2011

Простой бит: [mutableAttributedString insertAttributedString: @ "• \ t" atIndex: 0];

Жесткий бит.Что-то вроде следующего.(Это извлечено из более крупного проекта, но может дать вам достойное начало.)

NSMutableAttributedString * string = [[NSMutableAttributedString alloc] initWithString:@"•\texample bullet fill out the text to check what happens on the second line and make sure it is lining up OK"];

CTTextAlignment alignment = kCTLeftTextAlignment;
CGFloat paragraphSpacing = 0.0;
CGFloat paragraphSpacingBefore = 0.0;
CGFloat firstLineHeadIndent = 15.0;
CGFloat headIndent = 30.0;

CGFloat firstTabStop = 15.0; // width of your indent
CGFloat lineSpacing = 0.45;

CTTextTabRef tabArray[] = { CTTextTabCreate(0, firstTabStop, NULL) };

CFArrayRef tabStops = CFArrayCreate( kCFAllocatorDefault, (const void**) tabArray, 1, &kCFTypeArrayCallBacks );
CFRelease(tabArray[0]);

CTParagraphStyleSetting altSettings[] = 
{
    { kCTParagraphStyleSpecifierLineSpacing, sizeof(CGFloat), &lineSpacing},
    { kCTParagraphStyleSpecifierAlignment, sizeof(CTTextAlignment), &alignment},
    { kCTParagraphStyleSpecifierFirstLineHeadIndent, sizeof(CGFloat), &firstLineHeadIndent},
    { kCTParagraphStyleSpecifierHeadIndent, sizeof(CGFloat), &headIndent},
    { kCTParagraphStyleSpecifierTabStops, sizeof(CFArrayRef), &tabStops},
    { kCTParagraphStyleSpecifierParagraphSpacing, sizeof(CGFloat), &paragraphSpacing},
    { kCTParagraphStyleSpecifierParagraphSpacingBefore, sizeof(CGFloat), &paragraphSpacingBefore}
}; 

CTParagraphStyleRef style;
style = CTParagraphStyleCreate( altSettings, sizeof(altSettings) / sizeof(CTParagraphStyleSetting) );

if ( style == NULL )
{
    NSLog(@"*** Unable To Create CTParagraphStyle in apply paragraph formatting" );
    return;
}

[string addAttributes:[NSDictionary dictionaryWithObjectsAndKeys:(NSObject*)style,(NSString*) kCTParagraphStyleAttributeName, nil] range:NSMakeRange(0,[string length])];

CFRelease(tabStops);
CFRelease(style);

Вам необходимо включить инфраструктуру CoreText, а затем импортировать CoreText / CoreText.h

32 голосов
/ 12 сентября 2014

Вот более современный подход, который работает с iOS6:

NSMutableAttributedString * string = [[NSMutableAttributedString alloc] initWithString:@"•\texample bullet fill out the text to check what happens on the second line and make sure it is lining up OK"];

NSMutableParagraphStyle *paragraphStyle;
paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[paragraphStyle setTabStops:@[[[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft location:15 options:nil]]];
[paragraphStyle setDefaultTabInterval:15];
[paragraphStyle setFirstLineHeadIndent:0];
[paragraphStyle setHeadIndent:15];

[string addAttributes:@{NSParagraphStyleAttributeName: paragraphStyle} range:NSMakeRange(0,[string length])];
18 голосов
/ 26 октября 2017

Вот хорошее решение со Swift

let label = UILabel()
label.frame = CGRect(x: 40, y: 100, width: 280, height: 600)
label.textColor = UIColor.lightGray
label.numberOfLines = 0

let arrayString = [
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
    "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
    "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
    "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
]

label.attributedText = add(stringList: arrayString, font: label.font, bullet: "")

self.view.addSubview(label)

Добавить атрибуты маркера

Swift 4.2 ++

func add(stringList: [String],
         font: UIFont,
         bullet: String = "\u{2022}",
         indentation: CGFloat = 20,
         lineSpacing: CGFloat = 2,
         paragraphSpacing: CGFloat = 12,
         textColor: UIColor = .gray,
         bulletColor: UIColor = .green) -> NSAttributedString {

    let textAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: textColor]
    let bulletAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: bulletColor]

    let paragraphStyle = NSMutableParagraphStyle()
    let nonOptions = [NSTextTab.OptionKey: Any]()
    paragraphStyle.tabStops = [
        NSTextTab(textAlignment: .left, location: indentation, options: nonOptions)]
    paragraphStyle.defaultTabInterval = indentation
    //paragraphStyle.firstLineHeadIndent = 0
    //paragraphStyle.headIndent = 20
    //paragraphStyle.tailIndent = 1
    paragraphStyle.lineSpacing = lineSpacing
    paragraphStyle.paragraphSpacing = paragraphSpacing
    paragraphStyle.headIndent = indentation

    let bulletList = NSMutableAttributedString()
    for string in stringList {
        let formattedString = "\(bullet)\t\(string)\n"
        let attributedString = NSMutableAttributedString(string: formattedString)

        attributedString.addAttributes(
            [NSAttributedString.Key.paragraphStyle : paragraphStyle],
            range: NSMakeRange(0, attributedString.length))

        attributedString.addAttributes(
            textAttributes,
            range: NSMakeRange(0, attributedString.length))

        let string:NSString = NSString(string: formattedString)
        let rangeForBullet:NSRange = string.range(of: bullet)
        attributedString.addAttributes(bulletAttributes, range: rangeForBullet)
        bulletList.append(attributedString)
    }

    return bulletList
}

Swift 4.0 и 4.1

func add(stringList: [String],
         font: UIFont,
         bullet: String = "\u{2022}",
         indentation: CGFloat = 20,
         lineSpacing: CGFloat = 2,
         paragraphSpacing: CGFloat = 12,
         textColor: UIColor = .gray,
         bulletColor: UIColor = .green) -> NSAttributedString {

    let textAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: textColor]
    let bulletAttributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: bulletColor]

    let paragraphStyle = NSMutableParagraphStyle()
    let nonOptions = [NSTextTab.OptionKey: Any]()
    paragraphStyle.tabStops = [
        NSTextTab(textAlignment: .left, location: indentation, options: nonOptions)]
    paragraphStyle.defaultTabInterval = indentation
    //paragraphStyle.firstLineHeadIndent = 0
    //paragraphStyle.headIndent = 20
    //paragraphStyle.tailIndent = 1
    paragraphStyle.lineSpacing = lineSpacing
    paragraphStyle.paragraphSpacing = paragraphSpacing
    paragraphStyle.headIndent = indentation

    let bulletList = NSMutableAttributedString()
    for string in stringList {
        let formattedString = "\(bullet)\t\(string)\n"
        let attributedString = NSMutableAttributedString(string: formattedString)

        attributedString.addAttributes(
            [NSAttributedStringKey.paragraphStyle : paragraphStyle],
            range: NSMakeRange(0, attributedString.length))

        attributedString.addAttributes(
            textAttributes,
            range: NSMakeRange(0, attributedString.length))

        let string:NSString = NSString(string: formattedString)
        let rangeForBullet:NSRange = string.range(of: bullet)
        attributedString.addAttributes(bulletAttributes, range: rangeForBullet)
        bulletList.append(attributedString)
    }

    return bulletList
}

Вот результат:

enter image description here

5 голосов
/ 11 июля 2011

Вы не реализуете маркированный список со стилем абзаца в iOS.Установите табуляцию по своему усмотрению, а затем вставьте вкладку, маркер, вкладку в начале абзаца.

CTParagraphStyle довольно негибкая, поэтому вы не можете просто добавить новые стиливыбирая это.Однако вы можете добавить любой понравившийся вам атрибут (MYBulletStyle) к произвольным прогонам в пределах NSAttributedString.Это может быть полезно для передачи информации о списке маркеров с помощью NSAttributedString, а затем перестроения строки для включения маркеров, когда вы будете готовы ее отобразить.Но Core Text не будет отображать маркеры автоматически.

1 голос
/ 23 июля 2013

Не фактический ответ на этот вопрос, но это может помочь.

просто добавьте "•"

Даже я искал что-то подобное для моего textView.То, что я сделал, просто добавьте вышеуказанную строку с моей строкой и передайте ее моему textView, то же самое можно сделать и для меток.Я ответил на это для будущего зрителя.

0 голосов
/ 18 июля 2018

Вот превосходный ответ Крунала в Objective-C .Он также удаляет интервал между абзацами в последнем элементе маркера, чтобы избежать дополнительного нижнего отступа в UILabel.

UILabel *label = [UILabel new];
label.frame = CGRectMake(40, 100, 280, 600);
label.textColor = UIColor.lightGrayColor;
label.numberOfLines = 0;

NSArray *stringArray = @[@"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
                         @"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
                         @"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
                         @"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
                         ];

label.attributedText = [self attributedStringForBulletTexts:stringArray
                                                   withFont:label.font
                                               bulletString:@""
                                                indentation:20
                                                lineSpacing:2
                                           paragraphSpacing:12
                                                  textColor:UIColor.grayColor
                                                bulletColor:UIColor.greenColor];

А вот функция, которая создает фактический приписанный текст:

- (NSAttributedString *)attributedStringForBulletTexts:(NSArray *)stringList
                                              withFont:(UIFont *)font
                                          bulletString:(NSString *)bullet
                                           indentation:(CGFloat)indentation
                                           lineSpacing:(CGFloat)lineSpacing
                                      paragraphSpacing:(CGFloat)paragraphSpacing
                                             textColor:(UIColor *)textColor
                                           bulletColor:(UIColor *)bulletColor {

    NSDictionary *textAttributes = @{NSFontAttributeName: font,
                                 NSForegroundColorAttributeName: textColor};
    NSDictionary *bulletAttributes = @{NSFontAttributeName: font, NSForegroundColorAttributeName: bulletColor};

    NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
    paragraphStyle.tabStops = @[[[NSTextTab alloc] initWithTextAlignment: NSTextAlignmentLeft location:indentation options:@{}]];
    paragraphStyle.defaultTabInterval = indentation;
    paragraphStyle.lineSpacing = lineSpacing;
    paragraphStyle.paragraphSpacing = paragraphSpacing;
    paragraphStyle.headIndent = indentation;

    NSMutableAttributedString *bulletList = [NSMutableAttributedString new];

    for (NSString *string in stringList) {
        NSString *formattedString = [NSString stringWithFormat:@"%@\t%@\n", bullet, string];
        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:formattedString];
        if ([string isEqualToString: stringList.lastObject]) {
            paragraphStyle = [paragraphStyle mutableCopy];
            paragraphStyle.paragraphSpacing = 0;
        }
        [attributedString addAttributes:@{NSParagraphStyleAttributeName: paragraphStyle} range:NSMakeRange(0, attributedString.length)];
        [attributedString addAttributes:textAttributes range:NSMakeRange(0, attributedString.length)];

        NSRange rangeForBullet = [formattedString rangeOfString:bullet];
        [attributedString addAttributes:bulletAttributes range:rangeForBullet];
        [bulletList appendAttributedString:attributedString];
    }

    return bulletList;
}
...