0

In Objective-C, I am trying to make a NSTextField, when clicked, open a sheet with a NSDatePicker that slides out under the text field. You select a date which closes the sheet and populates the NSTextField with the date chosen.

I have found this article on how to use a protocol to do this in Swift. http://www.knowstack.com/swift-nsdatepicker-sample-code/#comment-20440

But when I convert it to Objective-C I have a few issues.

The first time I click my button to trigger the sheet, the sheet appears in the middle of the screen, ignoring the event:

-(NSRect)window:(NSWindow *)window willPositionSheet:(NSWindow *)sheet usingRect:(NSRect)rect {

When I select a date, the textfield in the main xib is updated with the selection so the protocol part is working but the sheet remains unresponsive on screen.

If I click the button a second time, the unresponsive sheet closes and reappears under the NSTextField and dismisses itself when I choose a date. This is the expected behaviour.

My question is, why does this not work the first time I click the button but only works the second time?

Here is the code:

#import <Cocoa/Cocoa.h>


@protocol DatePickerProtocol
@required
    -(void) selectedDate:(NSDate *)date;
@optional
@end


@interface datePickerWindowController : NSWindowController {
    id delegate;
}

-(void)setDelegate:(id)newDelegate;

@end

#import "datePickerWindowController.h"


@interface datePickerWindowController ()
    @property (weak) IBOutlet NSDatePicker *datePicker;
@end

@implementation datePickerWindowController

- (void)windowDidLoad {
    [super windowDidLoad];

    self.datePicker.dateValue = [NSDate date];
}

-(void)setDelegate:(id)newDelegate {
    delegate = newDelegate;
    NSLog(@"delegate has been set in datePickerWindowController");
}


- (IBAction)selectDate:(NSDatePicker *)sender {
    [delegate selectedDate:self.datePicker.dateValue];
    [self.window close];
}

@end

#import <Cocoa/Cocoa.h>
#import "datePickerWindowController.h"


@interface AppDelegate : NSObject <NSApplicationDelegate, DatePickerProtocol, NSWindowDelegate>

@end

#import "AppDelegate.h"

@interface AppDelegate ()
    @property (weak) IBOutlet NSWindow *window;
    @property (weak) IBOutlet NSDatePicker *timePicker;
    @property (weak) IBOutlet NSTextField *textDate;
    @property (retain) datePickerWindowController * myDatePickerWindowController;
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    self.window.delegate = self;
    [self.window setDelegate:self];

    self.textDate.stringValue = [NSString stringWithFormat:@"%@",[NSDate date]];

    datePickerWindowController * windowController = [[datePickerWindowController alloc] initWithWindowNibName:@"datePickerWindowController"];


    self.myDatePickerWindowController = windowController;
    self.myDatePickerWindowController.delegate = self;
    [self.myDatePickerWindowController setDelegate:self];
}


- (void)applicationWillTerminate:(NSNotification *)aNotification {
}

-(void)selectedDate:(NSDate *)date {
    self.textDate.stringValue = [NSString stringWithFormat:@"%@", date];

}

- (IBAction)pickDateButton:(NSButton *)sender {

    [self.window beginSheet:self.myDatePickerWindowController.window completionHandler:nil];
}

// Position sheet under text field
-(NSRect)window:(NSWindow *)window willPositionSheet:(NSWindow *)sheet usingRect:(NSRect)rect {
    if (sheet == self.myDatePickerWindowController.window) {
        NSRect r = self.textDate.frame;
        r.origin.y = r.origin.y + 5;
        return r;
    } else {
        return rect;
    }
}

@end

I am assuming I have the delegate messed up somehow. Maybe in the xib or the code. I can not see why it works a second time though. Is this due to retain or how I am keeping the DatePicker around.

Many thanks for any help.

GeoffCoope
  • 952
  • 9
  • 20

0 Answers0