如何迭代属性字符串中的所有字体?

时间:2014-12-27 05:05:49

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

有人可以帮我转换为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字典,因此在使用NSDictionary之前必须将其转换为enumerateKeysandObjectsUsingBlock,这是正确的?

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

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

1 个答案:

答案 0 :(得分:0)

迭代字典中的所有条目,寻找密钥有点多余。字典的重点是你可以直接获得密钥的值:

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)然后你可以在块中安全地使用该字体。

查找最小值/最大值是很好的减少使用例如给定一系列具有某些属性的值,您希望找到最小值:

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

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