UITextView和NSAttributedString以及自定义属性不起作用

8

使用UITextView时,我尝试向富文本字符串中添加自定义属性。然而,在将其赋值给UITextView的attributedText后,所有自定义键都会丢失。例如:

NSMutableAttributedString *lString = [[ NSMutableAttributedString alloc ] initWithString: @"astring"
                                             attributes: @{ @"customkey": @"customvalue" }];
NSLog(@"string: %@", lString);  // shows customkey present
textView.attributedText = lString;
NSLog(@"result: %@", self.textView.attributedText);   // shows customkey missing

这是否能正常工作?

1
你使用了哪些自定义属性?我不明白 UITextView 如何知道如何呈现自定义属性。你需要使用其中一个文档中记录的属性。 - rmaddy
自定义属性。如果我使用文档中记录的属性,它就能正常工作。它现在可以知道它们但保留它们而不是丢弃它们,对吧? - Kristof Van Landschoot
你能解释一下你希望 UITextView 怎么知道你的自定义属性吗?你试图做什么? - rmaddy
1
我正在尝试在UITextField中添加"astring",并保留关于"astring"的信息,例如"customkey"设置为"customvalue",即使用户在"astring"之前、之后添加字符或将"astring"更改为"foobar"。我只希望UITextView不会像忘记设置的字体一样忘记自定义键,即使用户在其周围键入其他内容或更改单词。它不必呈现或执行任何其他操作,只需保留它即可。 - Kristof Van Landschoot
在我的iOS 7上似乎运行良好。@KristofVanLandschoot,您是否仍然遇到此问题? - julien_c
3个回答

18

从iOS 7开始,现在它可以按照您的期望工作:

来自访问属性

属性字符串通过名称标识属性,在NSDictionary对象中存储属性名称下的值,该对象又与指示字典属性适用于哪些字符的NSRange相关联。 除了标准属性外,您可以为一系列字符分配任何属性名称值对。

它适用于标准和NSTextStorage(文本套件)支持的UITextView。


听起来就是我需要的。我已经不再在代码的那部分工作了。采用iOS 7并检查一下是个很好的理由! - Kristof Van Landschoot

6
根据评论,您正在试图滥用NSAttributedString。NSAttributedString和UITextView仅设计处理文档化的属性。您可能能够最初在字符串中存储自定义属性,但是一旦文本视图开始处理属性文本并且您要求文本视图提供最新的属性文本时,文本视图将长时间摆脱任何自定义属性。
更好的解决方案是创建一个扩展UITextView的类。您的子类应添加一个属性,可以保存您想要的任何自定义属性。或者,您的自定义类可能会覆盖attributedText和“setAttributedText:”方法。这些将负责保存和恢复属性字符串中找到的任何自定义属性。
注意:此答案适用于iOS 6及更早版本。对于iOS 7,请参见下面@julien_c的答案。

1
文档并未声称支持自定义属性。文档介绍了它支持的键。除非文档明确说明支持某些内容,否则必须假定不支持。无法记录不支持的内容。地球上没有足够大的存储设备来记录不支持的内容。 :) - rmaddy
2
对我来说,这听起来像是合理的推论:UITextView支持属性字符串,而属性字符串支持自定义键,因此UITextView将与具有自定义键的属性字符串一起使用。文档中的一些警告会更好。但我明白你的意思 :) - Kristof Van Landschoot
2
“属性字符串通过名称来标识属性,使用NSDictionary对象将值存储在给定名称下。您可以为一系列字符分配任何属性名称/值对,自定义属性的解释由您的应用程序决定(请参阅《属性字符串编程指南》)。”然而,苹果的UIKit控件似乎不会保留自定义属性。这将是一个很好的功能。 - karwag
2
这个被接受的答案已经过时了,因为下面的答案说iOS 7接受自定义属性。 - fatuhoku
2
@fatuhoku 事物随着时间变化而变化。留下评论供未来读者参考是可以的。指出答案现在已经过时并没有错。但不要对曾经正确的答案进行负评。否则,由于API和功能的变化,您可能会花费余生时间来对过时的答案进行负投票。您不能期望人们每次API更新时都回去更新所有答案。 - rmaddy
显示剩余3条评论

3

1
这不再是真的了,因为UITextView现在由TextKit支持而不是WebKit,对吧? - Suragch
1
@Suragch 是的,我相信自从iOS 8以来,它会显示实际的属性字符串。 - Cocoanetics

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接