jonjbar
jonjbar

Reputation: 4066

Have a property pointing to another property

In my iPhone project, I have a common "date editing" view which features a UIDatePicker. I would like to use this view to update one NSDate property based on the way it's called.

The way I thought about achieving that is to have an NSDate property called CurrentlyEditedDate which I set to point to the correct NSDate property I could like to edit. But I don't know how to do that.

Let's say I have 2 NSDate properties defined:

@property (nonatomic, retain) NSDate *startDate;
@property (nonatomic, retain) NSDate *endDate;

When I launch my view I would like to do the following:

CurrentlyEditedDate = startDate

Or the following based on the caller:

CurrentlyEditedDate = endDate

So that my view can edit any NSDate object. However I don't know how to define or assign the CurrentlyEditedDate property. Nor do I know how to set it up from the view to a new NSDate value.

Upvotes: 1

Views: 112

Answers (2)

atticus
atticus

Reputation: 960

I think actually the best solution here would be to implement a delegate protocol. It looks a little thornier, but it won't be as fragile as trying to store the variable reference.

Here's what you need to do:

First, declare the protocol so that other classes know what to implement in order to receive your delegate messages. Also, create a .delegate property so that other objects can tell your date picker that they want to get those messages:

// MyDatePicker.h
#import <Cocoa/Cocoa.h>

@class MyDatePicker;
@protocol MyDatePickerDelegate <NSObject>
- (void)myDatePicker:(MyDatePicker *)datePicker didChangeDate:(NSDate *)date;
@end

@interface MyDatePickerViewController : UIViewController {
    id<MyDatePickerDelegate> delegate;
}

@property (nonatomic, assign) id<MyDatePickerDelegate> delegate;

@end

Then when you get a new date from your picker, you just need to check to see if you have a delegate, and that they have implemented your method. If they have, just go ahead and tell them about the new date:

// MyDatePickerViewController.m
#import "MyDatePickerViewController.h"

@implementation MyDatePickerViewController

- (void)changedDate:(NSDate *)newDate {
    if ([delegate respondsToSelector:@selector(myDatePicker:didChangeDate:)]) {
        [delegate myDatePicker:self didChangeDate:newDate];
    }
}

@end

Then, in your class where you want to receive the date info you might do something like this:

- (void)createDatePicker {
    MyDatePicker *datePicker = [[MyDatePicker alloc] init];
    datePicker.delegate = self;
}

- (void)myDatePicker:(MyDatePicker *)datePicker didChangeDate:(NSDate *)date {

    if (startTimeOrSomething) {
        self.startDate = date;
    } else {
        self.endDate = date;
    }
}

I just typed that without compiling, but it should be correct. This may seem like a lot of work, but it will very quickly become second nature, and is a much more robust way to handle these kinds of situations.

Upvotes: 3

Chris Cooper
Chris Cooper

Reputation: 17564

You just need to call the setCurrentlyEditedDate:(NSDate* date) method that exists as a result of creating the property.

[myDateViewController setCurrentlyEditedDate: startDate];

If you call this where you create and initialize the view controller for the date picker, it will assign the NSDate property (which is a pointer already) to point to the startDate NSDate object.

Upvotes: 1

Related Questions