如何子类NSTextAttachment?

Dun*_*ald 13 nstextattachment objective-c-category

这是我的问题:

我使用Core Data来存储来自iOS和/或OS X应用程序的富文本输入,并希望将图像粘贴到NSTextView或UITextView中,以便:a)保留其原始分辨率,b)在显示屏上进行缩放以正确调整textView,这意味着根据设备上视图的大小进行缩放.

目前我正在使用- (void)textStorage:(NSTextStorage *)textStorage didProcessEditing:(NSTextStorageEditActions)editedMask range:(NSRange)editedRange changeInLength:(NSInteger)delta查找附件,然后生成具有比例因子的图像并将其分配给textAttachment.image属性.

这样做是因为我只是改变了比例因子并保留了原始图像,但我相信更优雅的解决方案是使用NSTextAttachmentContainer子类并从中返回一个适当大小的CGREct

- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex
Run Code Online (Sandbox Code Playgroud)

所以我的问题是如何创建和插入这样的子类?

我是否使用textStorage:didProcessEditing迭代每个附件并将NSTextAttachmentContainer替换为我自己的类,或者我可以简单地创建一个Category,然后以某种方式使用此类别来更改默认行为.后者似乎不那么具有侵入性,但如何让我的textViews自动使用这个类别呢?

糟糕:刚刚注意到NSTextAttachmentContainer是一个协议,所以我假设然后在NSTextAttachment上创建一个类别,并覆盖上面的方法是一个选项.

嗯:不能使用Category来覆盖现有的类方法,所以我想子类化是唯一的选择,在这种情况下如何让UITextView使用我的附件子类,或者我必须迭代使用referencedString来替换所有NSTextAttachments MYTextAttachment的实例.将此字符串取消归档到OS X上会产生什么影响,比如默认的OS X NSTextAttachment(与iOS类不同)?

小智 17

基于这篇优秀的文章,如果你想利用

- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex
Run Code Online (Sandbox Code Playgroud)

要缩放图像文本附件,您必须创建自己的NSTextAttachment子类

@interface MYTextAttachment : NSTextAttachment 
@end
Run Code Online (Sandbox Code Playgroud)

在执行中使用scale操作:

@implementation MYTextAttachment

- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex {
    CGFloat width = lineFrag.size.width;

    // Scale how you want
    float scalingFactor = 1.0;   
    CGSize imageSize = [self.image size];   
    if (width < imageSize.width)
        scalingFactor = width / imageSize.width;
    CGRect rect = CGRectMake(0, 0, imageSize.width * scalingFactor, imageSize.height * scalingFactor);

    return rect;
}
@end
Run Code Online (Sandbox Code Playgroud)

基于

lineFrag.size.width
Run Code Online (Sandbox Code Playgroud)

它给你(或我所理解的)textView所采用的宽度,你将(将)设置属性文本"嵌入"你的自定义文本附件.

一旦创建了NSTextAttachment的子类,您所要做的就是使用它.创建一个实例,设置一个图像,然后用它创建一个新的属性字符串,并将其附加到每个示例的NSMutableAttributedText:

MYTextAttachment* _textAttachment = [MYTextAttachment new];
_textAttachment.image = [UIImage ... ];

[_myMutableAttributedString appendAttributedString:[NSAttributedString attributedStringWithAttachment:_immediateTextAttachment]];
Run Code Online (Sandbox Code Playgroud)

有关信息,似乎

 - (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex 
Run Code Online (Sandbox Code Playgroud)

每当要求textview重新编辑时调用.

希望它有所帮助,即使它没有回答你问题的每个方面.

  • 是的,谢谢我写了那篇文章! (16认同)