Nstextattachment Image Not Shown in Nstextview (But in Uitextview)

NSTextAttachment image not shown in NSTextView (but in UITextView)?

var thumbnailImage: NSImage? = // some image
var attachmentCell: NSTextAttachmentCell = NSTextAttachmentCell.initImageCell(thumbnailImage!)
var attachment: NSTextAttachment = NSTextAttachment()
attachment.attachmentCell = attachmentCell
var attrString: NSAttributedString = NSAttributedString.attributedStringWithAttachment(attachment)
self.textView.textStorage().appendAttributedString(attrString)

How to pull NSImage from NSTextAttachment in NSTextView?

Since the NSImage was created with an NSTextAttachmentCell, it must be retrieved from the attachment cell. The key is to cast the cell as NSCell and then grab the image property. So, replacing the section of code from the original

if z != nil {
let cell = z!.attachmentCell as? NSCell
if cell != nil {
let image = cell?.image
}
}

NSTextView copy paste NSTextAttachment on mac os

I had a similar issue. Not sure if it is exactly what you want, but I wanted to be able to copy and paste an NSTextAttachment's string representation.

I ended up overriding func writeSelection(to pboard: NSPasteboard, type: String) -> Bool in my custom NSTextView class:

override func writeSelection(to pboard: NSPasteboard, type: String) -> Bool {
let selectedAttributedString = attributedString().attributedSubstring(from: selectedRange())
let selectedAttributedStringCopy = NSMutableAttributedString(attributedString: selectedAttributedString)

selectedAttributedStringCopy.enumerateAttribute(NSAttachmentAttributeName, in: NSMakeRange(0,(selectedAttributedString.string.characters.count)), options: .reverse, using: {(_ value: Any?, _ range: NSRange, _ stop: UnsafeMutablePointer<ObjCBool>) -> Void in

if let textAttachment = value as? NSTextAttachment, let textAttachmentCell = textAttachment.attachmentCell as? YouCustomTextAttachmentCellClass {
var range2: NSRange = NSRange(location: 0,length: 0)
let attributes = selectedAttributedStringCopy.attributes(at: range.location, effectiveRange: &range2)

selectedAttributedStringCopy.replaceCharacters(in: range, with: NSMutableAttributedString(string: textAttachmentCell.yourStringRepresentation))
selectedAttributedStringCopy.addAttributes(attributes, range: range)

// selectedAttributedStringCopy.insert(attachmentAttributedString, at: range.location)

}
})

pboard.clearContents()
pboard.writeObjects([selectedAttributedStringCopy])

return true
}

Note that I am using a custom NSTextAttachmentCell class that also remembers it's string representation.

NSTextView insert image in between text

Insert NSImage into NSTextView:

NSImage * pic = [[NSImage alloc] initWithContentsOfFile:@"/Users/Anne/Desktop/Sample.png"];
NSTextAttachmentCell *attachmentCell = [[NSTextAttachmentCell alloc] initImageCell:pic];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
[attachment setAttachmentCell: attachmentCell ];
NSAttributedString *attributedString = [NSAttributedString attributedStringWithAttachment: attachment];
[[textView textStorage] appendAttributedString:attributedString];

In the header file:

IBOutlet id textView;

How to subclass NSTextAttachment?

Based on this excellent article, if you want to make use of

- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex

to scale an image text attachment, you have to create your own subclass of NSTextAttachment

@interface MYTextAttachment : NSTextAttachment 
@end

with the scale operation in the implementation:

@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

based on

lineFrag.size.width

which give you (or what I have understood as) the width taken by the textView on which you have (will) set the attributed text "embedding" your custom text attachment.

Once the subclass of NSTextAttachment created, all you have to do is make use of it. Create an instance of it, set an image, then create a new attributed string with it and append it to a NSMutableAttributedText per example:

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

[_myMutableAttributedString appendAttributedString:[NSAttributedString attributedStringWithAttachment:_immediateTextAttachment]];

For info it seems that

 - (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex 

is called whenever the textview is asked to be relayout-ed.

Hope it helps, even though it doesn't answer every aspect of your problem.



Related Topics



Leave a reply



Submit