如何将 NSAttributedString 中的字符大小写更改为大写

发布于 11-24 02:24 字数 72 浏览 5 评论 0原文

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

谢谢,

I want to convert NSAttributedString containing RTFD to uppercase without losing attributes of existing characters and graphics.

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

愿与i2024-12-01 02:24:46

编辑:

@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. 重新应用所有属性。

EDIT:

@fluidsonic Is correct that the original code is incorrect. Below is an updated version in Swift, that replaces the text in each attribute range with an uppercased version of the string in that range.

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

Original answer:

- (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;
}

What this does:

  1. Makes a mutable copy of the input attributed string.
  2. Takes all the attributes from that string and puts them in an array so they can be used later.
  3. Makes an uppercase plain string using built-in NSString method.
  4. Re-applys all the attributes.

相对绾红妆2024-12-01 02:24:46

当您大写德语“ß”字符时,它会变成“SS”;因此范围发生变化。这可能会导致接受的答案崩溃。以下是我针对此案例的建议:

extension NSAttributedString {
  func uppercased() -> NSAttributedString {
    // Original NSAttributedString
    let originalAttributedString = self
    // Convert the attributed string to a regular string
    let originalString = originalAttributedString.string
    // Uppercase the string
    let uppercasedString = originalString.uppercased()
    // Create a new mutable attributed string with the uppercased string
    let uppercasedAttributedString = NSMutableAttributedString(string: uppercasedString)
    // Track the difference in length due to character count changes
    var indexOffset = 0

    originalAttributedString.enumerateAttributes(in: NSRange(location: 0, length: originalAttributedString.length),
                                                 options: []) { attributes, range, _ in

      // Extract the substring from the original string for this range
      let originalSubstring = originalAttributedString.attributedSubstring(from: range).string

      // Uppercase the substring
      let uppercasedSubstring = originalSubstring.uppercased()

      // Calculate the difference in length between the original and uppercased substrings
      let lengthDifference = uppercasedSubstring.count - originalSubstring.count

      // Adjust the range for the uppercased string (apply indexOffset before adjustment)
      let adjustedRange = NSRange(location: range.location + indexOffset, length: uppercasedSubstring.count)

      // Apply attributes to the new range in the uppercased attributed string
      uppercasedAttributedString.addAttributes(attributes, range: adjustedRange)

      // Update the index offset for future ranges
      indexOffset += lengthDifference
    }

    return uppercasedAttributedString
  }
}

When you uppercase German "ß" character, it becomes "SS"; therefore the range changes. This might cause crash in the accepted answer. Here's my proposal to cover this case as well:

extension NSAttributedString {
  func uppercased() -> NSAttributedString {
    // Original NSAttributedString
    let originalAttributedString = self
    // Convert the attributed string to a regular string
    let originalString = originalAttributedString.string
    // Uppercase the string
    let uppercasedString = originalString.uppercased()
    // Create a new mutable attributed string with the uppercased string
    let uppercasedAttributedString = NSMutableAttributedString(string: uppercasedString)
    // Track the difference in length due to character count changes
    var indexOffset = 0

    originalAttributedString.enumerateAttributes(in: NSRange(location: 0, length: originalAttributedString.length),
                                                 options: []) { attributes, range, _ in

      // Extract the substring from the original string for this range
      let originalSubstring = originalAttributedString.attributedSubstring(from: range).string

      // Uppercase the substring
      let uppercasedSubstring = originalSubstring.uppercased()

      // Calculate the difference in length between the original and uppercased substrings
      let lengthDifference = uppercasedSubstring.count - originalSubstring.count

      // Adjust the range for the uppercased string (apply indexOffset before adjustment)
      let adjustedRange = NSRange(location: range.location + indexOffset, length: uppercasedSubstring.count)

      // Apply attributes to the new range in the uppercased attributed string
      uppercasedAttributedString.addAttributes(attributes, range: adjustedRange)

      // Update the index offset for future ranges
      indexOffset += lengthDifference
    }

    return uppercasedAttributedString
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文