Edit AllPages

I wrote FakeImageView to give me true proportional scaling and a few other features.


#import <AppKit/AppKit.h>

@interface FakeImageView : NSView { NSImage *_image; NSColor *_bgColor; NSImageScaling _scaling; }


#import “FakeImageView.h”

@implementation FakeImageView


When necessary, I create a FakeImageView subclass of NSView in IB and set image views to that custom class. Maybe it would have been better to subclass NSImageView … but oh well. Your mileage may vary.

– MikeTrent

Here is how to add Drag and Drop support to this class (from finder). Insert this into the init function:

[self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];

Then implement the following methods:

If you want to implement archiving support for this class change the @Implementation line to look like this:

@interface FakeImageView : NSView

And add the following methods:

-(void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:_image]; [coder encodeObject:_bgColor]; [coder encodeValueOfObjCType:@encode(NSImageScaling) at:&_scaling];


-(id)initWithCoder:(NSCoder *)coder { if (self = [super initWithCoder:coder]) { [self setImage:[coder decodeObject]]; [self setBackgroundColor:[coder decodeObject]]; [coder decodeValueOfObjCType:@encode(NSImageScaling) at:&_scaling];

} return self; }

Any optimizations encouraged :)

Also I suggest replacing NSRectFill(bounds); with [NSBezierPath fillRect: [self bounds]]; because the latter allows you to set background to clearColor.


Some suggestions to clean up the mutator calls a bit:

Saves you a few autorelease pool dependencies which could make debugging trickier (I hate it when something crashes outside of the event loop because of an autorelease mistake). It also makes the code a little cleaner.

Also, a bit of a technicality, but there should probably be a super call in the drawRect: method. Since the background is being redrawn by this code it might not matter but it is always nice in case the NSView implementation in the future wants to do something else.

Almost forgot that this will require that you set _image to nil in the initWithFrame: method (and the initWithCoder: if you are using that).

Someone else can insert these modifications in place if they want to but I didn’t want to step on any toes in case you guys had some reason for doing it this way.


Here is some code to allow the use of the rest of the image drag and drop destination functionality. I haven’t tested it all myself since I don’t have any pict or eps on my drive but it should work.

Firstly, the initWithFrame:

Then the performDragOperation:

That should work. More information on Drag and Drop Destinations can be found in this tutorial:


See also: NSImageViewIsJustKidding

Why doesn’t this page wrap properly (in mozilla)?

Because of the HTML preformatted text tag. It doesn’t wrap. We’re (sort of) working on it… – RobRix

Easiest way to fix that is to manually wrap the long line … – SimonWoodside

Did it. – UliKusterer

Wouldn’t it be more efficient to apply an NSAffineTransform to the view rather than copy the whole image?

You tell me. Implement the change, measure its performance, and post the results. – MikeTrent

I didn’t make the suggestion, but I implemented image scaling and translation (user dragging the image around the view) with NSAffineTransform and it’s incredibly fast. I don’t have hard numbers, but I was able to update the image so quickly I could see screen tearing when dragging the image around the view. On my dual 2.0, both processors were hovering round 25-30% while dragging continuously using NSAffineTransform as opposed to 50-60% for the copy.

I actually had to slow it down and only ‘[self setNeedsDisplay: YES];’ every other call to mouseDragged, it was too fast.

if you want the same apearance as with NSImageView, use NSCompositeSourceOver instead of NSCompositeCopy

I think this would be better as a category. Maybe modify the first category on the NSImageCategory page so that it can do either type of scaling. Then you could use a normal NSImageView for display and that first category would actually be useful.

I figured since I suggested it I might as well just do it. You can always revert NSImageCategory if it’s not ok to borrow. :)