I found a work around to the problem. In the example code below, in response to a color change the action message, newColor:, changes the color of the image and calls the button's setImage: message. This actually is the same NSImage object already in the Button. In this case the API ignores the setNeedsDisplay message.
If a new NSImage object is created, as in the line commented out, and sent to the Button, the Button is redrawn with the new image.
I still think it is a bug that the in the first instance the setNeedsDisplay message is ignored.
// AppDelegate.m
// TestUI
//
// Created by Bruce D MacKenzie on 11/20/22.
//
#import "AppDelegate.h"
@interface AppDelegate ()
{
}
@property (strong) IBOutlet NSWindow *window;
@property (assign) IBOutlet NSButton *theButton;
@end
@implementation AppDelegate
{
NSImage *image;
}
@synthesize theButton;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
-(void)awakeFromNib
{
image = [[NSImage alloc] initWithSize: NSMakeSize( 32 , 32 )];
[image lockFocus];
[[NSColor redColor] drawSwatchInRect: NSMakeRect(0, 0, 32, 32)];
[image unlockFocus];
[[self theButton] setImage: image];
}
- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app {
return YES;
}
-(IBAction)newColor: (NSColorWell *)sender
{
NSColor *newColor;
newColor = [sender color];
// image = [[NSImage alloc] initWithSize: NSMakeSize( 32 , 32 )];
[image lockFocus];
[newColor drawSwatchInRect: NSMakeRect( 0, 0, 32, 32)];
[image unlockFocus];
[[self theButton] setImage: image];
[[self theButton] setNeedsDisplay: YES];
}
code-block