I've looked at other delegate questions but there weren't any good existing answers. Everything should be set up properly, I can see my slider will change value in logs. For some reason, the delegate function numberOfSquaresInSquareView() never fires when I call it from squareView, and the squareView delegate call just returns nil. I know I am fairly close since this closely matches some lessons I've found, but I think I am missing something. The changeSquareCount() works and I can see in logs that it saves the value.
squareView.h
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@class SquareView;
@protocol SquareViewDelegate <NSObject>
- (NSNumber *)numberOfSquaresInSquareView:(SquareView *)squareView;
@end
@interface SquareView : NSView
@property (nonatomic, weak) id<SquareViewDelegate> delegate;
@end
NS_ASSUME_NONNULL_END
squareView.m
#import "SquareView.h"
@implementation SquareView
@synthesize delegate;
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
NSLog(@"drawing rect");
[[NSColor redColor]set];
//NSNumber *num = ; //cound pass in nil, dont matter
NSLog(@"squares to draw: %@", [delegate numberOfSquaresInSquareView:self]);
// Drawing code here.
}
@end
AppController.h
#import <Foundation/Foundation.h>
#import "SquareView.h"
//@class SquareView;
NS_ASSUME_NONNULL_BEGIN
@interface AppController : NSObject <SquareViewDelegate>
@property (retain) IBOutlet SquareView *squareView;
- (IBAction)changeSquareCount:(id)sender;
@end
NS_ASSUME_NONNULL_END
AppController.m
#import "AppController.h"
@implementation AppController
{
NSNumber *_squareCount;
}
@synthesize squareView = _squareView;
- (void)awakeFromNib
{
[_squareView setDelegate:nil];
_squareCount = @(10);
[_squareView setNeedsDisplay:YES];
}
- (void)changeSquareCount:(id)sender
{
_squareCount = @([sender intValue]);
NSLog(@"square count stored: %@",_squareCount);
[_squareView setNeedsDisplay:YES];
}
-(NSNumber *)numberOfSquaresInSquareView:(SquareView *) squareView
{
NSLog(@"triggering numberOfSquaresInSquareView");
return _squareCount;
}
@end
The delegate
has to 'retain' somewhere to make it work. As I can see here, the SquareView
is a sub-view of AppController
, and the delegate
works like SquareView <-> AppController
. It's a kind of callback in this case. However, you're assigning it to nil
by [_squareView setDelegate:nil]
It should be:
_squareView.delegate = self;
By doing that, every time drawRect
in SquareView gets called, it will trigger numberOfSquaresInSquareView
in AppController, and in this case, it will print out
squares to draw: 10