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
Xcode 4.2 with Arc: Will My Code Run Even on iOS Devices with Firmware Older Than 5.0
Uitabbar Change Background Color of One UItabbaritem on iOS7
iOS 7 Weather App Expand/Collapse Transition
Does "Let _ = ..." (Let Underscore Equal) Have Any Use in Swift
How to Fetch Images from Photo Library Within Range of Two Dates in iOS
Spritekit Swift Node Count Issues
Firebase Database Not Equal Request - Alternative Solution (For iOS)
Paste Formatted Text, Not Images or HTML
Native-Like Momentum-Scrolling on Body in iOS Webapp
Testflight Sdk and iOS Simulator - How to Use
How to Queue Multiple Accessibility Notifications for Voiceover
How to Make Inputaccessoryview Appear Above Uitabbarviewcontroller's Tabs
iOS 8 [Uiapplication Sharedapplication].Scheduledlocalnotifications Empty
Why Use Corebluetooth Connectperipheral Did Not Call Delegate Methods in iOS8