BallotCreateTableCell.m 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // _____ _
  2. // |_ _| |_ _ _ ___ ___ _ __ __ _
  3. // | | | ' \| '_/ -_) -_) ' \/ _` |_
  4. // |_| |_||_|_| \___\___|_|_|_\__,_(_)
  5. //
  6. // Threema iOS Client
  7. // Copyright (c) 2014-2020 Threema GmbH
  8. //
  9. // This program is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU Affero General Public License, version 3,
  11. // as published by the Free Software Foundation.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU Affero General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Affero General Public License
  19. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. #import "BallotCreateTableCell.h"
  21. #import "UIImage+ColoredImage.h"
  22. #import "Colors.h"
  23. @interface BallotCreateTableCell () <UITextFieldDelegate>
  24. @property (nonatomic, strong) UILabel *allDayLabel;
  25. @end
  26. @implementation BallotCreateTableCell
  27. - (void)awakeFromNib {
  28. [super awakeFromNib];
  29. [_choiceTextField setPlaceholder:NSLocalizedStringFromTable(@"ballot_placeholder_choice", @"Ballot", nil)];
  30. _choiceTextField.delegate = self;
  31. [Colors updateKeyboardAppearanceFor:_choiceTextField];
  32. [_dateButton setImage:[UIImage imageNamed:@"Calendar" inColor:[Colors main]] forState:UIControlStateNormal];
  33. [_dateButton setAccessibilityLabel:NSLocalizedStringFromTable(@"ballot_date_button", @"Ballot", nil)];
  34. }
  35. - (void)setChoice:(BallotChoice *)choice {
  36. [_choiceTextField setText: choice.name];
  37. _choice = choice;
  38. }
  39. - (void)didEnterChoiceText {
  40. _choice.name = _choiceTextField.text;
  41. if (_delegate) {
  42. [_delegate didUpdateCell: self];
  43. }
  44. }
  45. - (void)dateChanged {
  46. [self setTextForChoiceField];
  47. }
  48. - (void)setTextForChoiceField {
  49. if (_allDaySwitch.on) {
  50. _choiceTextField.text = [NSString stringWithFormat:@"%@", [DateFormatter getDayMonthAndYear:_datePicker.date]];
  51. } else {
  52. if (@available(iOS 14.0, *)) {
  53. // do not round the time for iOS 14
  54. } else {
  55. NSTimeInterval seconds = ceil([_datePicker.date timeIntervalSinceReferenceDate]/300.0)*300.0;
  56. _datePicker.date = [NSDate dateWithTimeIntervalSinceReferenceDate:seconds];
  57. }
  58. _choiceTextField.text = [NSString stringWithFormat:@"%@", [DateFormatter getFullDateFor:_datePicker.date]];
  59. }
  60. _choice.name = _choiceTextField.text;
  61. }
  62. - (void)changePickerMode:(id)sender {
  63. UISwitch *allDaySwitch = (UISwitch *)sender;
  64. CGFloat timeLabelHeight = 38.0;
  65. if (_allDaySwitch.on) {
  66. _datePicker.datePickerMode = UIDatePickerModeDate;
  67. if (@available(iOS 14.0, *)) {
  68. _datePicker.frame = CGRectMake(_datePicker.frame.origin.x, _datePicker.frame.origin.y, _datePicker.frame.size.width, _datePicker.frame.size.height - timeLabelHeight);
  69. }
  70. } else {
  71. _datePicker.datePickerMode = UIDatePickerModeDateAndTime;
  72. if (@available(iOS 14.0, *)) {
  73. if (allDaySwitch != nil) {
  74. _datePicker.frame = CGRectMake(_datePicker.frame.origin.x, _datePicker.frame.origin.y, _datePicker.frame.size.width, _datePicker.frame.size.height + timeLabelHeight);
  75. }
  76. }
  77. }
  78. if (_choiceTextField.text.length)
  79. [self setTextForChoiceField];
  80. }
  81. - (void)setInputText:(NSDate *)date allDay:(BOOL)allDay {
  82. NSDate *timeDate = [DateFormatter getDateFromFullDateString:_choiceTextField.text];
  83. NSDate *normalDate = [DateFormatter getDateFromDayMonthAndYearDateString:_choiceTextField.text];
  84. if (timeDate == nil && normalDate == nil) {
  85. _datePicker.date = date;
  86. if (allDay) {
  87. _datePicker.datePickerMode = UIDatePickerModeDate;
  88. } else {
  89. _datePicker.datePickerMode = UIDatePickerModeDateAndTime;
  90. }
  91. _allDaySwitch.on = allDay;
  92. }
  93. [self setTextForChoiceField];
  94. }
  95. - (void)addPicker {
  96. if (@available(iOS 14.0, *)) {
  97. self.datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, _choiceTextField.frame.origin.y + _choiceTextField.frame.size.height + 8.0, self.contentView.frame.size.width, 355.0)];
  98. } else {
  99. self.datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0.0, _choiceTextField.frame.origin.y + _choiceTextField.frame.size.height, self.contentView.frame.size.width, 216.0)];
  100. }
  101. if (@available(iOS 14.0, *)) {
  102. _datePicker.minuteInterval = 1;
  103. _datePicker.preferredDatePickerStyle = UIDatePickerStyleInline;
  104. } else {
  105. _datePicker.minuteInterval = 5;
  106. }
  107. [_datePicker setValue:[Colors main] forKey:@"textColor"];
  108. [_datePicker addTarget:self action:@selector(dateChanged) forControlEvents:UIControlEventValueChanged];
  109. _datePicker.alpha = 0.0;
  110. [self addSubview:_datePicker];
  111. CGFloat space = 0.0;
  112. if (@available(iOS 14.0, *)) {
  113. space = 8.0;
  114. }
  115. _allDayLabel = [[UILabel alloc] initWithFrame:CGRectMake(_choiceTextField.frame.origin.x, _datePicker.frame.origin.y + _datePicker.frame.size.height + space, _choiceTextField.frame.size.width, 31.0)];
  116. _allDayLabel.text = NSLocalizedStringFromTable(@"ballot_allDay_switch", @"Ballot", nil);
  117. _allDayLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline];
  118. [_allDayLabel setValue:[Colors fontNormal] forKey:@"textColor"];
  119. _allDayLabel.alpha = 0.0;
  120. [_allDayLabel setIsAccessibilityElement:NO];
  121. [_allDayLabel setAccessibilityElementsHidden:YES];
  122. [self addSubview:_allDayLabel];
  123. _allDaySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(self.frame.size.width - 20.0 - 51.0, _datePicker.frame.origin.y + _datePicker.frame.size.height + space, 51.0, 31.0)];
  124. [_allDaySwitch addTarget:self action:@selector(changePickerMode:) forControlEvents:UIControlEventValueChanged];
  125. _allDaySwitch.alpha = 0.0;
  126. _allDaySwitch.accessibilityLabel = NSLocalizedStringFromTable(@"ballot_allDay_switch", @"Ballot", nil);
  127. [self addSubview:_allDaySwitch];
  128. UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
  129. }
  130. #pragma mark - text field delegate
  131. -(void)textFieldDidEndEditing:(UITextField *)textField {
  132. [self didEnterChoiceText];
  133. }
  134. -(BOOL)textFieldShouldReturn:(UITextField *)textField {
  135. [self didEnterChoiceText];
  136. return YES;
  137. }
  138. // track any changes
  139. -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
  140. NSString *newValue = [textField.text stringByReplacingCharactersInRange:range withString:string];
  141. _choice.name = newValue;
  142. return YES;
  143. }
  144. #pragma mark - Actions
  145. - (IBAction)showDatePicker:(id)sender {
  146. if (!_datePicker && !self.editing) {
  147. [self addPicker];
  148. NSDate *selectedDate = [DateFormatter getDateFromFullDateString:_choiceTextField.text];
  149. if (selectedDate != nil) {
  150. _datePicker.date = selectedDate;
  151. _allDaySwitch.on = false;
  152. } else {
  153. selectedDate = [DateFormatter getDateFromDayMonthAndYearDateString:_choiceTextField.text];
  154. if (selectedDate != nil) {
  155. _datePicker.date = selectedDate;
  156. _allDaySwitch.on = true;
  157. }
  158. }
  159. [self changePickerMode:nil];
  160. [_delegate showPickerForCell:self];
  161. [UIView animateWithDuration:0.35 animations:^{
  162. _datePicker.alpha = 1.0;
  163. _allDaySwitch.alpha = 1.0;
  164. _allDayLabel.alpha = 1.0;
  165. } completion:^(BOOL finished) {
  166. [_datePicker setIsAccessibilityElement:YES];
  167. [_datePicker setAccessibilityElementsHidden:NO];
  168. [_allDaySwitch setIsAccessibilityElement:YES];
  169. [_allDaySwitch setAccessibilityElementsHidden:NO];
  170. UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
  171. }];
  172. } else {
  173. [_delegate hidePickerForCell:self];
  174. [UIView animateWithDuration:0.2 animations:^{
  175. _datePicker.alpha = 0.0;
  176. _allDaySwitch.alpha = 0.0;
  177. _allDayLabel.alpha = 0.0;
  178. } completion:^(BOOL finished) {
  179. [_datePicker removeFromSuperview];
  180. [_allDaySwitch removeFromSuperview];
  181. [_allDayLabel removeFromSuperview];
  182. _datePicker = nil;
  183. }];
  184. }
  185. }
  186. @end