[object Object]In a project I am developing with Xcode a 2d layout of the faces of Rubik's cube is displayed (see the attached Screenshot). In the center of each face's representation is a NSColorWell. The other eight cubes on that face are represented as NSButtons displaying an NSImage of the appropriate color. In response to the user selecting a new color the program resets the eight Button's image to one of the new color.
The problem is that this change is not reflected on the display even if the NSButton is sent a setNeedsDisplay message. Sending the NSButton a display message also has no effect. The change is not seen until the Button receives a mouse click or interestingly if the window is dragged from the main screen to a second screen.
I believe this a bug in AppKit.
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