更改UITextView字体w / o删除粗体/下划线/斜体格式

我在iOS应用程序中有一个UITextView,我想让用户随意粗体/斜体/下划线/等,所以我给文本视图上的allowEditingTextAttributes属性设置为true。 不过,我也想让用户改变字体和颜色等东西。 目前,甚至改变UITextView的颜色属性也会重置UITextView的格式(即去除粗体/斜体等)。 有没有办法改变这个不重置格式? 作为参考,我目前正在做这个改变颜色:

self.textView.textColor = colorTheUserPicked //a UIColor picked by the user 

编辑 :其实,这是我的坏,我也重置文本属性本身的值,当我改变颜色。 删除允许我根据需要更改颜色。 但是,我仍然不能改变字体,甚至没有删除粗体/斜体等字体大小。 我意识到这可能是不可能的,虽然…

我将使用Objective-C解决scheme进行回答,因为我没有在Swift中编写代码,但它应该很容易转换成Swift。

NSAttributedString “效果”存储在一个NSDictionary 。 所以这是一个关键:价值体系(Key的唯一性)。
粗体/斜体(从你的例子)在NSFontAttributedName的值。 这就是为什么你不能像这样重新设置。

主键是使用enumerateAttributesInRange:options:usingBlock: ::

 [attr enumerateAttributesInRange:NSMakeRange(0, [attr length]) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(NSDictionary *attributes, NSRange range, BOOL *stop) { NSMutableDictionary *newAttributes = [attributes mutableCopy]; //Do changes [attr addAttributes:newAttributes range:range]; //Apply effects }]; 

以下行在“//更改”位置。 所以,如果你想改变字体大小:

 if ([newAttributes objectForKey:NSFontAttributeName]) { UIFont *currentFont = (UIFont *)[attributes objectForKey:NSFontAttributeName]; UIFont *newFont = [UIFont fontWithName:[currentFont fontName] size:[currentFont pointSize]*0.5];//Here, I multiplied the previous size with 0.5 [newAttributes setValue:newFont forKey:NSFontAttributeName]; } 

如果你想粗体/斜体等你可能会对UIFontDescriptor感兴趣的字体,以及相关的问题 。

它向你展示了如何获得以前的字体,并改变一个与前一个字体有一些共同点的新字体。

如果你想改变颜色:

 if ([newAttributes objectForKey:NSForegroundColorAttributeName])//In case if there is some part of the text without color that you don't want to override, or some custom- things { UIColor *newColor = [UIColor blueColor]; [newAttributes setValue:newColor forKey:NSForegroundColorAttributeName]; } 

下划线效果在NSUnderlineStyleAttributeName的值中。 所以模拟更改可以完成。

谢谢@Larme! 你的解决scheme是正确的,所以我接受了! Swift版本供参考:

 //needs to be a mutable attributed string var mutableCopy = NSMutableAttributedString(attributedString: textView.attributedText) //make range var textRange = NSMakeRange(0, textView.attributedText.length) //get all the string attributes textView.attributedText.enumerateAttributesInRange(textRange, options: NSAttributedStringEnumerationOptions.LongestEffectiveRangeNotRequired, usingBlock: { (attributes, range, stop) -> Void in //make a copy of the attributes we can edit var newAttributes = attributes as [NSObject : AnyObject] if newAttributes[NSFontAttributeName] != nil { //if the font attr exists //create a new font with the old font name and new size let currentFont = newAttributes[NSFontAttributeName] as UIFont let newFont = UIFont(name: currentFont.fontName, size: currentFont.pointSize * 0.5) //set new font size to half of old size //replace the nsfontattribute's font with the new one newAttributes[NSFontAttributeName] = newFont } //replace the old attributes with the new attributes to the mutable version mutableCopy.addAttributes(newAttributes, range: range) }) //replace the old attributed text with the newly attributed text textView.attributedText = mutableCopy 

为Xamarin.IOS的C#实现类似。

  NSError error = null; var htmlString = new NSAttributedString(NSUrl.FromFilename( "About.html"), new NSAttributedStringDocumentAttributes {DocumentType = NSDocumentType.HTML}, ref error); var mutableCopy = new NSMutableAttributedString(htmlString); htmlString.EnumerateAttributes(new NSRange(0, htmlString.Length), NSAttributedStringEnumeration.LongestEffectiveRangeNotRequired, (NSDictionary attributes, NSRange range, ref bool stop) => { var newMutableAttributes = new NSMutableDictionary(attributes); if (newMutableAttributes[UIStringAttributeKey.Font] != null) { var currentFont = newMutableAttributes[UIStringAttributeKey.Font] as UIFont; if (currentFont != null) { var newFontName = currentFont.Name; if (currentFont.Name.Equals("TimesNewRomanPS-BoldItalicMT")) { newFontName = "HelveticaNeue-BoldItalic"; } else if (currentFont.Name.Equals("TimesNewRomanPS-ItalicMT")) { newFontName = "HelveticaNeue-Italic"; } else if (currentFont.Name.Equals("TimesNewRomanPS-BoldMT")) { newFontName = "HelveticaNeue-Bold"; } else if (currentFont.Name.Equals("TimesNewRomanPSMT")) { newFontName = "HelveticaNeue"; } newMutableAttributes.SetValueForKey(UIFont.FromName(newFontName, currentFont.PointSize * 1.5f), UIStringAttributeKey.Font); // = newFont; } else { newMutableAttributes.SetValueForKey(UIFont.FromName("HelveticaNeue", 14), UIStringAttributeKey.Font); // Default to something. } } mutableCopy.AddAttributes(newMutableAttributes, range); }); aboutTextView.AttributedText = mutableCopy;