views:

454

answers:

2

Is it possible to use an image as a background for a Text Field in Cocoa? If so, how?

+1  A: 

I don't know if this is the "correct" way to do it, but the first thing that comes to mind would be to make a custom subclass of NSTextField, which might look roughly like this:

- (void)awakeFromNib
{
    [self setDrawsBackground:NO];
}

- (void)drawRect:(NSRect)rect
{
    [super drawRect:rect];

    [self lockFocus];
    [[NSImage imageNamed:@"<your image's filename>.png"] drawInRect:rect
        fromRect:rect
        operation:NSCompositeSourceOver
        fraction:1.0];
    [self unlockFocus];
}

Again, that's a just rough outline of the essential parts.

Anyways, like I said, I'm not sure if this really the "correct" way to do it (or if there is even a "correct" way, for that matter), but this will give you a background image for your NSTextField.

Edit in response to Joshua's comment (I'm not going to have enough room in that tiny little comment box):

To add the image into your project, you'd drag it from wherever it is into the project window (the main list of files in the middle of the project window, although depending on how you've set up your Xcode editing environment, this might be different for you).

In order to subclass NSTextField, you would want to create a new Objective-C class file (File -> New File…), but edit the header so that the class inherits from NSTextField instead of NSObject. In other words, your header file might look like this:

#import <Cocoa/Cocoa.h>

@interface BGImageTextField : NSTextField
{
}

@end

As for the rest of the code, you would want to add that in the main body of the implementation file (BGImageTextField.m, for example), specifically in between the @implementation and @end keywords.

I'd also like to mention two things. First, I'd recommend picking up a copy of Cocoa Programming for Mac OS X, by Aaron Hillegass—it covers most of the Cocoa basics that I just went over, and is one of the best ways to learn Cocoa in general. Secondly, although my approach works, it's probably not the best approach—especially since I just recently found this post, which seems to hint at a better way of extending NSTextField.

htw
With your example above, the textField's cell won't draw. If you add [super drawRect:rect]; at the end of it, both that, and the focus ring drawing should work again. Since you already setDrawsBackground to NO, super's drawRect shouldn't mess anything up. Another thing that might mess things up is the fieldEditor's drawing of a background; not sure about that though. Final thing: You'll want to make sure the textField has a nearby opaque ancestor to prevent poor drawing performance.
Dirk Stoop
Ah, good point—I've edited my post to reflect that. (For some reason, when I first tried it out, calling drawRect: would draw over the background image.) In general, though, I wish there were a better way to approach this problem—it feels kind of like a hack at the moment.
htw
Thanks, 1 extra question though, where do you place the background image?
Joshua
Also, where would i enter all that code, sorry I'm new to cocoa. ;)
Joshua
No problem—I edited my post in response to your questions. Hope it helps! :)
htw
Do you need to connect the text field to the class, in some way, if so how? Thanks Again for you help!
Joshua
Also, What code do you need to enter in BGImageTextView.m ?
Joshua
First, I made a small mistake—the class should really be named "BGImageTextField", although naming is not a big issue. Second, yes, you would have to specify that the text field is an instance of BGImageTextField (the tab with the "i" icon inside the attributes window in Interface Builder). As for what to enter in BGImageTextField.m, those methods I outlined in the main post would be methods to add to the BGImageTextField class (although you won't have to declare them in the header file).
htw
In general, though, while I'm happy to help out and explain concepts, I'd advise you to read some Cocoa tutorials first to get a good understanding of basic Cocoa before you try this out (I recommend http://cocoadevcentral.com/, in addition to Hillegass's book). A lot of the answers to your questions are covered in these tutorials, and they are addressed in more detail than I'd be able to cover here. Trust me, once you have these concepts down, this kind of stuff becomes much easier. :)
htw
+2  A: 

Instead of subclassing NSTextField, just make the background color transparent [NSColor clearColor] and put the image behind it.

CajunLuke
I just tried that, and it doesn't quite work out for me. But I like the idea—it's a lot simpler than my method.
htw