如何将NSAttributedString中的字符转换为大写

11
我想将包含RTFD的NSAttributedString转换为大写,而不会丢失现有字符和图形的属性。

谢谢。

1个回答

13

编辑:

@fluidsonic是正确的,原始代码有误。下面是一个用Swift更新的版本,它用该范围内字符串的大写版本替换每个属性范围中的文本。

extension NSAttributedString {
    func uppercased() -> NSAttributedString {

        let result = NSMutableAttributedString(attributedString: self)

        result.enumerateAttributes(in: NSRange(location: 0, length: length), options: []) {_, range, _ in
            result.replaceCharacters(in: range, with: (string as NSString).substring(with: range).uppercased())
        }

        return result
    }
}

原始回答:

- (NSAttributedString *)upperCaseAttributedStringFromAttributedString:(NSAttributedString *)inAttrString {
    // Make a mutable copy of your input string
    NSMutableAttributedString *attrString = [inAttrString mutableCopy];

    // Make an array to save the attributes in
    NSMutableArray *attributes = [NSMutableArray array];

    // Add each set of attributes to the array in a dictionary containing the attributes and range
    [attrString enumerateAttributesInRange:NSMakeRange(0, [attrString length]) options:0 usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
        [attributes addObject:@{@"attrs":attrs, @"range":[NSValue valueWithRange:range]}];
    }];

    // Make a plain uppercase string
    NSString *string = [[attrString string]uppercaseString];

    // Replace the characters with the uppercase ones
    [attrString replaceCharactersInRange:NSMakeRange(0, [attrString length]) withString:string];

    // Reapply each attribute
    for (NSDictionary *attribute in attributes) {
        [attrString setAttributes:attribute[@"attrs"] range:[attribute[@"range"] rangeValue]];
    }

    return attrString;
}

这段代码的作用:

  1. 创建一个可变的输入属性字符串的副本。
  2. 将该字符串中的所有属性提取到一个数组中,以便后续使用。
  3. 使用内置的 NSString 方法创建一个大写的纯文本字符串。
  4. 重新应用所有属性。

2
代码不正确。它可能会产生属性字符串,其中属性偏移了几个字符,甚至可能会崩溃。该方法的实现依赖于初始字符串和大写字符串具有相同数量的字符。但是根据文档,“大小写转换不能保证对称或产生与原始字符串相同长度的字符串。”。 - fluidsonic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接