我在iOS应用程序中有一个UITextView,我希望允许用户随意使用粗体/斜体/下划线/等,所以我在文本视图中将allowEditingTextAttributes属性设置为true。但是,我还想让用户改变字体和颜色等内容。目前,似乎改变UITextView的颜色属性会重置UITextView的格式(即摆脱粗体/斜体/等)。有没有办法在不重置格式的情况下改变它?作为参考,我目前正在这样做以改变颜色:
self.textView.textColor = colorTheUserPicked //a UIColor picked by the user
编辑:实际上,这是我的不好,我在更改颜色时也重置了文本属性本身的值。删除它允许我根据需要更改颜色。但是,如果不删除粗体/斜体/等,我仍然无法更改字体甚至字体大小。我意识到这可能是不可能的,但是......
答案 0 :(得分:2)
我会用Objective-C解决方案回答,因为我没有在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
和a related question感兴趣的字体。
它向您展示如何获取上一个字体并更改获得一个新字体,其中包含一些与前一个字体相同的字体。
如果您想更改颜色:
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
的值。所以可以进行类比的改变。
答案 1 :(得分:1)
谢谢@Larme!你的解决方案是正确的,所以我接受了!这是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
答案 2 :(得分:1)
为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;