21 #import "UITableViewCell+FindTable.h" |
21 #import "UITableViewCell+FindTable.h" |
22 |
22 |
23 @implementation EditableCellView |
23 @implementation EditableCellView |
24 @synthesize delegate, textField, titleLabel, minimumCharacters, maximumCharacters, respectEditing, oldValue; |
24 @synthesize delegate, textField, titleLabel, minimumCharacters, maximumCharacters, respectEditing, oldValue; |
25 |
25 |
26 -(id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { |
26 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { |
27 if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { |
27 if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { |
28 delegate = nil; |
28 delegate = nil; |
29 |
29 |
30 textField = [[UITextField alloc] initWithFrame:CGRectZero]; |
30 textField = [[UITextField alloc] initWithFrame:CGRectZero]; |
31 textField.backgroundColor = [UIColor clearColor]; |
31 textField.backgroundColor = [UIColor clearColor]; |
38 textField.userInteractionEnabled = YES; |
38 textField.userInteractionEnabled = YES; |
39 textField.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; |
39 textField.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; |
40 [textField addTarget:self action:@selector(save:) forControlEvents:UIControlEventEditingDidEndOnExit]; |
40 [textField addTarget:self action:@selector(save:) forControlEvents:UIControlEventEditingDidEndOnExit]; |
41 |
41 |
42 [self.contentView addSubview:textField]; |
42 [self.contentView addSubview:textField]; |
43 //[textField release]; |
|
44 |
43 |
45 titleLabel = [[UILabel alloc] init]; |
44 titleLabel = [[UILabel alloc] init]; |
46 titleLabel.textAlignment = NSTextAlignmentLeft; |
45 titleLabel.textAlignment = NSTextAlignmentLeft; |
47 titleLabel.backgroundColor = [UIColor clearColor]; |
46 titleLabel.backgroundColor = [UIColor clearColor]; |
48 titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; |
47 titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; |
49 [self.contentView addSubview:titleLabel]; |
48 [self.contentView addSubview:titleLabel]; |
50 //[titleLabel release]; |
|
51 |
49 |
52 minimumCharacters = 1; |
50 minimumCharacters = 1; |
53 maximumCharacters = 64; |
51 maximumCharacters = 64; |
54 respectEditing = NO; |
52 respectEditing = NO; |
55 oldValue = nil; |
53 oldValue = nil; |
56 } |
54 } |
57 return self; |
55 return self; |
58 } |
56 } |
59 |
57 |
60 -(void) layoutSubviews { |
58 - (void)layoutSubviews { |
61 [super layoutSubviews]; |
59 [super layoutSubviews]; |
62 |
60 |
63 CGRect contentRect = self.contentView.bounds; |
61 CGRect contentRect = self.contentView.bounds; |
64 CGFloat boundsX = contentRect.origin.x; |
62 CGFloat boundsX = contentRect.origin.x; |
65 |
63 |
77 } |
75 } |
78 |
76 |
79 textField.frame = CGRectMake(boundsX+offset+10, skew+10, 300, [UIFont labelFontSize] + 4); |
77 textField.frame = CGRectMake(boundsX+offset+10, skew+10, 300, [UIFont labelFontSize] + 4); |
80 } |
78 } |
81 |
79 |
82 -(void) setSelected:(BOOL)selected animated:(BOOL)animated { |
80 - (void)setSelected:(BOOL)selected animated:(BOOL)animated { |
83 [super setSelected:selected animated:animated]; |
81 [super setSelected:selected animated:animated]; |
84 // Configure the view for the selected state |
82 // Configure the view for the selected state |
85 } |
|
86 |
|
87 -(void) dealloc { |
|
88 self.delegate = nil; |
|
89 releaseAndNil(oldValue); |
|
90 releaseAndNil(titleLabel); |
|
91 releaseAndNil(textField); |
|
92 [super dealloc]; |
|
93 } |
83 } |
94 |
84 |
95 #pragma mark - |
85 #pragma mark - |
96 #pragma mark textField delegate |
86 #pragma mark textField delegate |
97 // limit the size of the field to 64 characters like in original frontend |
87 // limit the size of the field to 64 characters like in original frontend |
98 -(BOOL) textField:(UITextField *)aTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { |
88 - (BOOL)textField:(UITextField *)aTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { |
99 return !([aTextField.text length] > self.maximumCharacters && [string length] > range.length); |
89 return !([aTextField.text length] > self.maximumCharacters && [string length] > range.length); |
100 } |
90 } |
101 |
91 |
102 // allow editing only if delegate is set and conformant to protocol, and if editableOnlyWhileEditing |
92 // allow editing only if delegate is set and conformant to protocol, and if editableOnlyWhileEditing |
103 -(BOOL) textFieldShouldBeginEditing:(UITextField *)aTextField { |
93 - (BOOL)textFieldShouldBeginEditing:(UITextField *)aTextField { |
104 return (delegate != nil) && |
94 return (delegate != nil) && |
105 [delegate respondsToSelector:@selector(saveTextFieldValue:withTag:)] && |
95 [delegate respondsToSelector:@selector(saveTextFieldValue:withTag:)] && |
106 (respectEditing) ? [self findTable].editing : YES; |
96 (respectEditing) ? [self findTable].editing : YES; |
107 } |
97 } |
108 |
98 |
109 // the textfield is being modified, update the navigation controller |
99 // the textfield is being modified, update the navigation controller |
110 -(void) textFieldDidBeginEditing:(UITextField *)aTextField{ |
100 - (void)textFieldDidBeginEditing:(UITextField *)aTextField{ |
111 // don't interact with table below |
101 // don't interact with table below |
112 [self findTable].scrollEnabled = NO; |
102 [self findTable].scrollEnabled = NO; |
113 |
103 |
114 self.oldValue = self.textField.text; |
104 self.oldValue = self.textField.text; |
115 |
105 |
116 UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Cancel",@"") |
106 UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Cancel",@"") |
117 style:UIBarButtonItemStylePlain |
107 style:UIBarButtonItemStylePlain |
118 target:self |
108 target:self |
119 action:@selector(cancel:)]; |
109 action:@selector(cancel:)]; |
120 [(UITableViewController *)delegate navigationItem].leftBarButtonItem = cancelButton; |
110 [(UITableViewController *)delegate navigationItem].leftBarButtonItem = cancelButton; |
121 [cancelButton release]; |
|
122 |
111 |
123 UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Save",@"") |
112 UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Save",@"") |
124 style:UIBarButtonItemStyleDone |
113 style:UIBarButtonItemStyleDone |
125 target:self |
114 target:self |
126 action:@selector(save:)]; |
115 action:@selector(save:)]; |
127 [(UITableViewController *)delegate navigationItem].rightBarButtonItem = saveButton; |
116 [(UITableViewController *)delegate navigationItem].rightBarButtonItem = saveButton; |
128 [saveButton release]; |
|
129 } |
117 } |
130 |
118 |
131 /* with this a field might remain in editing status even if the view moved; |
119 /* with this a field might remain in editing status even if the view moved; |
132 use method below instead that allows some more interaction |
120 use method below instead that allows some more interaction |
133 // don't accept 0-length strings |
121 // don't accept 0-length strings |
134 -(BOOL) textFieldShouldEndEditing:(UITextField *)aTextField { |
122 - (BOOL)textFieldShouldEndEditing:(UITextField *)aTextField { |
135 return ([aTextField.text length] > 0); |
123 return ([aTextField.text length] > 0); |
136 } |
124 } |
137 */ |
125 */ |
138 |
126 |
139 -(BOOL) textFieldShouldReturn:(UITextField *)aTextField { |
127 - (BOOL)textFieldShouldReturn:(UITextField *)aTextField { |
140 return ([aTextField.text length] >= self.minimumCharacters); |
128 return ([aTextField.text length] >= self.minimumCharacters); |
141 } |
129 } |
142 |
130 |
143 // the textfield has been modified, tell the delegate to do something |
131 // the textfield has been modified, tell the delegate to do something |
144 -(void) textFieldDidEndEditing:(UITextField *)aTextField { |
132 - (void)textFieldDidEndEditing:(UITextField *)aTextField { |
145 // this forces a save when user selects a new field |
133 // this forces a save when user selects a new field |
146 if ([self.textField.text isEqualToString:self.oldValue] == NO) |
134 if ([self.textField.text isEqualToString:self.oldValue] == NO) |
147 [self save:aTextField]; |
135 [self save:aTextField]; |
148 |
136 |
149 // restores default behaviour on caller |
137 // restores default behaviour on caller |
153 } |
141 } |
154 |
142 |
155 #pragma mark - |
143 #pragma mark - |
156 #pragma mark instance methods |
144 #pragma mark instance methods |
157 // the user wants to show the keyboard |
145 // the user wants to show the keyboard |
158 -(void) replyKeyboard { |
146 - (void)replyKeyboard { |
159 [self.textField becomeFirstResponder]; |
147 [self.textField becomeFirstResponder]; |
160 } |
148 } |
161 |
149 |
162 // the user pressed cancel so hide keyboard |
150 // the user pressed cancel so hide keyboard |
163 -(void) cancel:(id) sender { |
151 - (void)cancel:(id)sender { |
164 // reverts any changes and performs a fake save for removing the keyboard |
152 // reverts any changes and performs a fake save for removing the keyboard |
165 self.textField.text = self.oldValue; |
153 self.textField.text = self.oldValue; |
166 [self save:sender]; |
154 [self save:sender]; |
167 } |
155 } |
168 |
156 |
169 // send the value to the delegate (called before textFieldDidEndEditing) |
157 // send the value to the delegate (called before textFieldDidEndEditing) |
170 -(void) save:(id) sender { |
158 - (void)save:(id)sender { |
171 if (delegate == nil || [delegate respondsToSelector:@selector(saveTextFieldValue:withTag:)] == NO) |
159 if (delegate == nil || [delegate respondsToSelector:@selector(saveTextFieldValue:withTag:)] == NO) |
172 return; |
160 return; |
173 |
161 |
174 // don't save if the textfield is invalid |
162 // don't save if the textfield is invalid |
175 if ([self textFieldShouldReturn:textField] == NO) |
163 if ([self textFieldShouldReturn:textField] == NO) |