【问题标题】:How can I iterate over all the fonts in an attributed string?如何遍历属性字符串中的所有字体?
【发布时间】:2014-12-27 05:05:49
【问题描述】:

谁能帮我把它转换成 Swift:

NSAttributedString *attrString = self.attributedText;
NSRange rangeAll = NSMakeRange(0, attrString.length);


// First pass is to check the smallest and largest fontSize so we can prevent changes beyond that.

__block float smallestFontSize = 250;
__block float largestFontSize = 4;

[self.textStorage enumerateAttributesInRange:rangeAll options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:
 ^(NSDictionary *attributes, NSRange range, BOOL *stop) {

     // Iterate over each attribute and look for a Font Size
     [attributes enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
         if ([[key description] isEqualToString:@"NSFont"]) {
             UIFont *font = obj;
             float fontSize = font.pointSize + bySize;
             smallestFontSize = MIN(smallestFontSize, fontSize);
             largestFontSize = MAX(largestFontSize, fontSize);
         }

     }];
 }];

编辑:

好的解决了。似乎编译器只是在一段时间内努力解决问题并显示各种语法错误,直到它解决为止。似乎attrs 变量实际上不是NSDictionary 而是一个Swift 字典,所以在你可以使用enumerateKeysandObjectsUsingBlock 之前,有必要将它转换为NSDictionary,这是正确的吗?

如果有更好的方法请告诉我。

var smallestFontSize: CGFloat = 250
var largestFontSize: CGFloat = 4

self.textStorage.enumerateAttributesInRange(rangeAll, options: NSAttributedStringEnumerationOptions.LongestEffectiveRangeNotRequired, usingBlock: {
    attrs, range, stop in

    FLOG("")
    let dict = attrs as NSDictionary

    dict.enumerateKeysAndObjectsUsingBlock { key, obj, stop in

        if (key.description.isEqual("NSFont")) {
            let font = obj as UIFont
            let fontSize = font.pointSize + bySize
            smallestFontSize = min(smallestFontSize, fontSize);
            largestFontSize = max(largestFontSize, fontSize);
        }
    }
})

【问题讨论】:

  • 你有什么事情吗?任何特定的编译器错误?
  • 你试过这个转换成swift吗?这是一个非编码转换平台。请在此处提出您的困难或问题。
  • 这个问题似乎是题外话,因为它是关于从一种语言翻译成另一种语言。
  • 抱歉,我遇到了这么多奇怪的语法错误
  • 转换为 NSDictionary 然后使用 enumerateKeysAndObjecteUsingBlock 不是惯用的。你可以改用for (key, value) in dict { ... }。

标签: objective-c swift objective-c-blocks


【解决方案1】:

遍历字典中的所有条目以查找键有点多余。字典的重点是您可以直接获取键的值:

textStorage.enumerateAttributesInRange(rangeAll, options: .LongestEffectiveRangeNotRequired) {
  attrs, range, stop in

    if let font = attrs?["NSFont"] as? UIFont {
        let fontSize = font.pointSize + bySize
        smallestFontSize = min(smallestFontSize, fontSize)
        largestFontSize = max(largestFontSize, fontSize)
    }

}

正如您所指出的,attrs 已经是一个 Swift 字典,那么为什么要将它转换回 NSDictionary 呢?但是您确实需要将从中获得的内容转换为有用的内容,因此需要调用as? UIFont。 if let 保证检查所有选项(例如 attrs 具有 NSFont 键并且它们的值是 NSFont)然后您可以在块内安全地使用字体。

查找最小值/最大值是 reduce 的一个很好的用途,例如给定具有某些属性的值序列,您希望找到以下值的最小值:

let (minVal,maxVal) = reduce(sequence, (250,4)) {
    (min($0.0,$1.someattr),max($0.1,$1.someattr))
}

你可以适应你的情况(即代替$1.someattr,获取字体大小,然后使用它,从你的块中返回生成的最小/最大元组)。但是,要做到这一点,而不是您的外部 enumerateAttributesInRange,您必须从 textStorage 获取一系列属性,不知道这是否可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2015-06-18
    • 2012-10-19
    相关资源
    最近更新 更多