从用户键入的属性字符串中查找属性 [英] Find attributes from attributed string that user typed

查看:193
本文介绍了从用户键入的属性字符串中查找属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,用户将键入他想要的任何内容,并且可以将文本设置为Bold,Italic和Underline。

In my app the User will type anything that he wants and he can make the text Bold, Italic and Underline.

我可以做文字 - 粗体,斜体和下划线。

I am able to do the Text - Bold, Italic and Underline.

但是我需要从属性字符串中找到哪个文字(或字符)粗体,斜体和下划线 用户输入

任何类型的链接,教程,代码都会有很大的帮助。

Any types of link, tutorial, code will be great help.

编辑:

我需要这样的结果...

I need the result like this...

如果字符6是Italic然后打印斜体。

如果字符14是粗体然后打印粗体。

if character 6 is Italic then print Italic.
if character 14 is Bold then print Bold.

我需要将所有文本从Calibri字体系列转换为HelveticaNeue字体系列而不更改其属性。

I need to convert all the text from Calibri font family to HelveticaNeue font family without changing it's attribute.

推荐答案

您可以使用此代码枚举属性(整个范围)。

You can enumerate the Attributes with this code (whole range).

[attrStr enumerateAttributesInRange:NSMakeRange(0, [attrStr length]) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:
         ^(NSDictionary *attributes, NSRange range, BOOL *stop) {
//Do something here
             }
         }];

对于特定范围,您必须更改代码 NSMakeRange(0,[ attrStr lenght])按您需要的范围。

For specific range, your have to change the code NSMakeRange(0, [attrStr lenght]) by the range you need.

编辑后,您的具体需求,此代码应该可以完成工作:

After your edit, your specific need, this code should do the work:

[attrStr enumerateAttributesInRange:NSMakeRange(0, [attrStr length])
                            options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
                         usingBlock:
 ^(NSDictionary *attributes, NSRange range, BOOL *stop)
{
     NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
     UIFont *currentFont = [mutableAttributes objectForKey: NSFontAttributeName];
     UIFont *newFont;
     if ([[currentFont fontName] isEqualToString:@"Calibri-BoldItalic"])
         newFont = [UIFont fontWithName:@"HelveticaNeue-BoldItalic" size:currentFont.pointSize];
     else if ([[currentFont fontName] isEqualToString:@"Calibri-Bold"])
         newFont = [UIFont fontWithName:@"HelveticaNeue-Bold" size:currentFont.pointSize];
     else if ([[currentFont fontName] isEqualToString:@"Calibri-Italic"])
         newFont = [UIFont fontWithName:@"HelveticaNeue-Italic" size:currentFont.pointSize];
    [mutableAttributes setObject:newFont forKey:@"NSFont"];
    [attrStr setAttributes:mutableAttributes range:range];
 }];

从你的评论中,你可能会看到更复杂的东西,所以我会给你一些想法/提示做/检查。你只需要完成我之前的代码来管理所有案例。

•案例:没有字体。

你只需检查 currentFont 是零。如果是,您可以设置所需内容。由于没有斜体/粗体属性(因为它们在字体中包含),我建议您设置为 newFont :HelveticaNeue。

•案例:这是Calibri的另一种字体。在那里它变得相当复杂。

我已经使用过了,在这里我得到了:
字体名称(这是 postscript名称)是这样的HelveticaNeue(如给出的例子):

From your comments, you may see more complicated things, so I will give you some ideas/tips to do/check. You'll just have to complete my previous code to manage all cases.
• Case: There is no font.
You just have to check if currentFont is nil. If yes, you set what you want. Since there is no attribute for italic/bold (since they are "included" in the font), I suggest you set for newFont: HelveticaNeue.
• Case: It's another font than Calibri. There it's quite more complicated.
I've worked with that, and here what I got: Font name (which is the postscript name) is made like this for HelveticaNeue (as given example):


HelveticaNeue

HelveticaNeue-Light

HelveticaNeue-UltraLight

HelveticaNeue-Medium

HelveticaNeue-LightItalic

HelveticaNeue-Italic

HelveticaNeue-UltraLightItalic

HelveticaNeue-Bold

HelveticaNeue-BoldItalic

HelveticaNeue-CondensedBold

HelveticaNeue-CondensedBlack

HelveticaNeue
HelveticaNeue-Light
HelveticaNeue-UltraLight
HelveticaNeue-Medium
HelveticaNeue-LightItalic
HelveticaNeue-Italic
HelveticaNeue-UltraLightItalic
HelveticaNeue-Bold
HelveticaNeue-BoldItalic
HelveticaNeue-CondensedBold
HelveticaNeue-CondensedBlack

所以你能想到的第一件事是:我只需检查名称的后缀(使用 hasSuffix:)。但这可能会出错。

的确,有些字体有一个代工厂后缀(我找到的是 LT MT EF )。

好​​吧,例如:

Times New Roman 真实姓名是 TimesNewRomanPSMT

它的斜体版本是 TimesNewRomanPS-ItalicMT

这就是为什么我们要检查它是否有代工厂后缀,因为 TimesNewRomanPSMT-Italic 将不起作用(因为它不存在,如果您尝试使用此名称设置字体,它将 nil )。

所以,据我所知,至于我可能有一些经验和我见过的案例,你可以做什么:
检查 [currentFont name] 包含: BoldItalic Italic Bold ,使用 NSRegularExpression rangeOfString:。请注意,我建议先检查 BoldItalic ,因为 Italic 可能会隐藏 Bold 就在它之前, Bold 可能会隐藏一个 Italic 就在它之后。

为了做到这一点,我建议您创建一个这样的方法(或这种方式):

So the first thing you could think of: I just have to check the suffix of the name (with hasSuffix:). But that may go wrong.
Indeed, some fonts have a foundry suffix (the ones I found are LT, MT, and EF).
Well, for example:
Times New Roman "real name" is TimesNewRomanPSMT.
And its italic version is TimesNewRomanPS-ItalicMT
That's why we have to check if it has a foundry suffix because TimesNewRomanPSMT-Italic won't work (since it doesn't exist, if you try to set a font with this name, it will be nil).
So, as far as I know, and as far I may have some experience and the case I've seen, what you could do: Check if the [currentFont name] contains either: BoldItalic, Italic or Bold, using a NSRegularExpression or a rangeOfString:. Note that I'd suggest to check before for BoldItalic since an Italic may "hides" a Bold just before it, and Bold may "hides" an Italic just after it.
In order to do so, I'd suggest that you create a method like this (or of this style):

-(UIFont)getCorrespondingHelveticaNeueFontMatchingCharacteriticsOf:(UIFont *)font
{
    UIFont *helveticaNueue;
    if (!font) //Checking if there is a font)
    {
        helveticaNueue = [UIFont fontWithName@"HelveticaNueue" size:defaultSizeYouSet];
    }
    else
    {
        //Check if it's BoldItalic/Italic/Bold
    }
    return helveticaNueue;
}

检查我之前提到的所有情况。

所以,从以前的代码中,您只需要替换 if 特定于 Calibri 的测试:

checking all the case I mentioned before.
So, from the previous code, you'll just have to replace the if tests that were working specificly for Calibri with:

UIFont *newFont = [self getCorrespondingHelveticaNeueFontMatchingCharacteriticsOf:currentFont];

现在你可能要做的第三部分(并将它们添加到你的测试中):
Black 字体是否需要作为 Bold 进行管理?好吧, Helvetica Neue 有这个属性,但您可能想直接使用黑色属性 Helvetica Neue ,并且可能想检查 currentFont 是否有它(以及另一种情况)。

Now a third part you may want to do (and add them to your test): Is the Black case of a font want to be managed as Bold? Well, Helvetica Neue has this "property", but you may want to use directly the black property for Helvetica Neue, and may want to check if currentFont has it (and again, another case).

编辑:
您可以使用iOS7以后我们可以使用 UIFontDescriptor 。您可以这样做:

You can use since iOS7 we can use UIFontDescriptor. Here is what you could do:

-(UIFont *)customFontMatchingFont:(UIFont *)otherFont
{
    NSString *customFontName = @"Helvetica"; //The custom font
    UIFont *tempFont = [UIFont fontWithName:customFontName size:[otherFont pointSize]]; 
    return [UIFont fontWithDescriptor:[[tempFont fontDescriptor] fontDescriptorWithSymbolicTraits:[[otherFont fontDescriptor] symbolicTraits]] size:[otherFont pointSize]];
}

注意:我没有检查所有情况(如果你的自定义家庭怎么办?没有匹配的字体,它返回什么?等等),但如果你不做太复杂的事情,这可能是一个很好的附加组件。

Note: I didn't check all the cases (what if your custom family doesn't have a matching font, what does it return? etc.), but that could be a nice add-on if you don't do too complicated things.

这篇关于从用户键入的属性字符串中查找属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆