XLFormLeftRightSelectorCell.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. //
  2. // XLFormLeftRightSelectorCell.m
  3. // XLForm ( https://github.com/xmartlabs/XLForm )
  4. //
  5. // Copyright (c) 2015 Xmartlabs ( http://xmartlabs.com )
  6. //
  7. //
  8. // Permission is hereby granted, free of charge, to any person obtaining a copy
  9. // of this software and associated documentation files (the "Software"), to deal
  10. // in the Software without restriction, including without limitation the rights
  11. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. // copies of the Software, and to permit persons to whom the Software is
  13. // furnished to do so, subject to the following conditions:
  14. //
  15. // The above copyright notice and this permission notice shall be included in
  16. // all copies or substantial portions of the Software.
  17. //
  18. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. // THE SOFTWARE.
  25. #import "UIView+XLFormAdditions.h"
  26. #import "XLFormRightImageButton.h"
  27. #import "NSObject+XLFormAdditions.h"
  28. #import "XLFormLeftRightSelectorCell.h"
  29. @interface XLFormLeftRightSelectorCell() <UIActionSheetDelegate>
  30. @end
  31. @implementation XLFormLeftRightSelectorCell
  32. {
  33. UITextField * _constraintTextField;
  34. }
  35. @synthesize leftButton = _leftButton;
  36. @synthesize rightLabel = _rightLabel;
  37. #pragma mark - Properties
  38. -(UIButton *)leftButton
  39. {
  40. if (_leftButton) return _leftButton;
  41. _leftButton = [[XLFormRightImageButton alloc] init];
  42. [_leftButton setTranslatesAutoresizingMaskIntoConstraints:NO];
  43. UIImageView * imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"XLForm.bundle/forwardarrow.png"]];
  44. [imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
  45. [_leftButton addSubview:imageView];
  46. [_leftButton addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[image(8)]|" options:0 metrics:0 views:@{@"image": imageView}]];
  47. UIView * separatorTop = [UIView autolayoutView];
  48. UIView * separatorBottom = [UIView autolayoutView];
  49. [_leftButton addSubview:separatorTop];
  50. [_leftButton addSubview:separatorBottom];
  51. [_leftButton addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[separatorTop(separatorBottom)][image][separatorBottom]|" options:0 metrics:0 views:@{@"image": imageView, @"separatorTop": separatorTop, @"separatorBottom": separatorBottom}]];
  52. _leftButton.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 15);
  53. [_leftButton setTitleColor:[UIColor colorWithRed:0.0 green:0.478431 blue:1.0 alpha:1.0] forState:UIControlStateNormal];
  54. [_leftButton setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled];
  55. [_leftButton setContentHuggingPriority:500 forAxis:UILayoutConstraintAxisHorizontal];
  56. return _leftButton;
  57. }
  58. -(UILabel *)rightLabel
  59. {
  60. if (_rightLabel) return _rightLabel;
  61. _rightLabel = [UILabel autolayoutView];
  62. [_rightLabel setTextColor:[UIColor grayColor]];
  63. [_rightLabel setTextAlignment:NSTextAlignmentRight];
  64. return _rightLabel;
  65. }
  66. -(XLFormLeftRightSelectorOption *)leftOptionForDescription:(NSString *)description
  67. {
  68. if (description){
  69. return [[self.rowDescriptor.selectorOptions filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
  70. return ([description isEqual:[((XLFormLeftRightSelectorOption *)evaluatedObject).leftValue displayText]]);
  71. }]] firstObject];
  72. }
  73. @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"" userInfo:nil];
  74. }
  75. -(XLFormLeftRightSelectorOption *)leftOptionForOption:(id)option
  76. {
  77. if (option){
  78. return [[self.rowDescriptor.selectorOptions filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
  79. XLFormLeftRightSelectorOption * evaluatedLeftOption = (XLFormLeftRightSelectorOption *)evaluatedObject;
  80. return [evaluatedLeftOption.leftValue isEqual:option];
  81. }]] firstObject];
  82. }
  83. @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"" userInfo:nil];
  84. }
  85. #pragma mark - XLFormDescriptorCell
  86. -(void)configure
  87. {
  88. [super configure];
  89. UIView * separatorView = [UIView autolayoutView];
  90. _constraintTextField = [UITextField autolayoutView];
  91. [_constraintTextField setText:@"Option"];
  92. _constraintTextField.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
  93. [separatorView setBackgroundColor:[UIColor colorWithWhite:0.85 alpha:1.0]];
  94. [self.contentView addSubview:_constraintTextField];
  95. [_constraintTextField setHidden:YES];
  96. [self.contentView addSubview:self.leftButton];
  97. [self.contentView addSubview:self.rightLabel];
  98. [self.contentView addSubview:separatorView];
  99. [self.leftButton addTarget:self action:@selector(leftButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
  100. NSDictionary * views = @{@"leftButton" : self.leftButton, @"rightLabel": self.rightLabel, @"separatorView": separatorView, @"constraintTextField": _constraintTextField };
  101. [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.leftButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]];
  102. [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[constraintTextField]" options:0 metrics:nil views:views]];
  103. [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[leftButton]-[separatorView(1)]-[rightLabel]-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:views]];
  104. [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[separatorView(20)]" options:0 metrics:nil views:views]];
  105. [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-12-[constraintTextField]-12-|" options:0 metrics:0 views:views]];
  106. }
  107. -(void)update
  108. {
  109. [super update];
  110. self.leftButton.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
  111. self.rightLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
  112. [self.leftButton setTitle:[NSString stringWithFormat:@"%@%@", [self.rowDescriptor.leftRightSelectorLeftOptionSelected displayText], self.rowDescriptor.required && self.rowDescriptor.sectionDescriptor.formDescriptor.addAsteriskToRequiredRowsTitle ? @"*" : @""] forState:UIControlStateNormal];
  113. [self.rowDescriptor setTitle:[self.rowDescriptor.leftRightSelectorLeftOptionSelected displayText]];
  114. self.rightLabel.text = [self rightTextLabel];
  115. [self.leftButton setEnabled:!self.rowDescriptor.isDisabled];
  116. self.accessoryView = self.rowDescriptor.isDisabled ? nil : [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"XLForm.bundle/forwardarrow.png"]];
  117. self.editingAccessoryView = self.accessoryView;
  118. self.selectionStyle = self.rowDescriptor.isDisabled ? UITableViewCellSelectionStyleNone : UITableViewCellSelectionStyleDefault;
  119. }
  120. -(NSString *)rightTextLabel
  121. {
  122. return (self.rowDescriptor.value ? [self.rowDescriptor.value displayText] : (self.rowDescriptor.leftRightSelectorLeftOptionSelected ? [self leftOptionForOption:self.rowDescriptor.leftRightSelectorLeftOptionSelected].noValueDisplayText : @""));
  123. }
  124. -(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)controller
  125. {
  126. if (self.rowDescriptor.leftRightSelectorLeftOptionSelected){
  127. XLFormLeftRightSelectorOption * option = [self leftOptionForOption:self.rowDescriptor.leftRightSelectorLeftOptionSelected];
  128. if (option.rightOptions){
  129. XLFormOptionsViewController * optionsViewController = [[XLFormOptionsViewController alloc] initWithStyle:UITableViewStyleGrouped];
  130. optionsViewController.title = option.selectorTitle;
  131. optionsViewController.rowDescriptor = self.rowDescriptor;
  132. [controller.navigationController pushViewController:optionsViewController animated:YES];
  133. }
  134. else{
  135. XLFormLeftRightSelectorOption * option = [self leftOptionForOption:self.rowDescriptor.leftRightSelectorLeftOptionSelected];
  136. Class selectorClass = option.rightSelectorControllerClass;
  137. UIViewController<XLFormRowDescriptorViewController> *selectorViewController = [[selectorClass alloc] init];
  138. selectorViewController.rowDescriptor = self.rowDescriptor;
  139. selectorViewController.title = self.rowDescriptor.selectorTitle;
  140. [controller.navigationController pushViewController:selectorViewController animated:YES];
  141. }
  142. }
  143. }
  144. -(NSString *)formDescriptorHttpParameterName
  145. {
  146. XLFormLeftRightSelectorOption * option = [self leftOptionForOption:self.rowDescriptor.leftRightSelectorLeftOptionSelected];
  147. return option.httpParameterKey;
  148. }
  149. - (id) chooseNewRightValueFromOption:(XLFormLeftRightSelectorOption*)option
  150. {
  151. switch (option.leftValueChangePolicy) {
  152. case XLFormLeftRightSelectorOptionLeftValueChangePolicyChooseLastOption:
  153. return [option.rightOptions lastObject];
  154. case XLFormLeftRightSelectorOptionLeftValueChangePolicyChooseFirstOption:
  155. return [option.rightOptions firstObject];
  156. case XLFormLeftRightSelectorOptionLeftValueChangePolicyNullifyRightValue:
  157. return nil;
  158. }
  159. return nil;
  160. }
  161. #pragma mark - Actions
  162. -(void)leftButtonPressed:(UIButton *)leftButton
  163. {
  164. #if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
  165. UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
  166. delegate:self cancelButtonTitle:nil
  167. destructiveButtonTitle:nil
  168. otherButtonTitles:nil];
  169. for (XLFormLeftRightSelectorOption * leftOption in self.rowDescriptor.selectorOptions) {
  170. [actionSheet addButtonWithTitle:[leftOption.leftValue displayText]];
  171. }
  172. actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
  173. actionSheet.tag = [self.rowDescriptor hash];
  174. [actionSheet showInView:self.formViewController.view];
  175. #else
  176. if ([UIAlertController class]) {
  177. UIAlertController * alertController = [UIAlertController alertControllerWithTitle:self.rowDescriptor.selectorTitle
  178. message:nil
  179. preferredStyle:UIAlertControllerStyleActionSheet];
  180. [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
  181. style:UIAlertActionStyleCancel
  182. handler:nil]];
  183. __weak __typeof(self)weakSelf = self;
  184. for (XLFormLeftRightSelectorOption * leftOption in self.rowDescriptor.selectorOptions) {
  185. [alertController addAction:[UIAlertAction actionWithTitle:[leftOption.leftValue displayText]
  186. style:UIAlertActionStyleDefault
  187. handler:^(UIAlertAction *action) {
  188. weakSelf.rowDescriptor.value = [self chooseNewRightValueFromOption:leftOption];
  189. weakSelf.rowDescriptor.leftRightSelectorLeftOptionSelected = [self leftOptionForDescription:[leftOption.leftValue displayText]].leftValue;
  190. [weakSelf.formViewController updateFormRow:weakSelf.rowDescriptor];
  191. }]];
  192. }
  193. [self.formViewController presentViewController:alertController animated:YES completion:nil];
  194. }
  195. #ifndef XL_APP_EXTENSIONS
  196. else{
  197. UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
  198. delegate:self cancelButtonTitle:nil
  199. destructiveButtonTitle:nil
  200. otherButtonTitles:nil];
  201. for (XLFormLeftRightSelectorOption * leftOption in self.rowDescriptor.selectorOptions) {
  202. [actionSheet addButtonWithTitle:[leftOption.leftValue displayText]];
  203. }
  204. actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
  205. actionSheet.tag = [self.rowDescriptor hash];
  206. [actionSheet showInView:self.formViewController.view];
  207. }
  208. #endif
  209. #endif
  210. }
  211. #if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
  212. #pragma mark - UIActionSheetDelegate
  213. - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
  214. {
  215. if ([actionSheet cancelButtonIndex] != buttonIndex){
  216. NSString * title = [actionSheet buttonTitleAtIndex:buttonIndex];
  217. if (![self.rowDescriptor.leftRightSelectorLeftOptionSelected isEqual:[self leftOptionForDescription:title].leftValue]){
  218. self.rowDescriptor.value = [self chooseNewRightValueFromOption:[self leftOptionForDescription:title]];
  219. self.rowDescriptor.leftRightSelectorLeftOptionSelected = [self leftOptionForDescription:title].leftValue;
  220. [self.formViewController updateFormRow:self.rowDescriptor];
  221. }
  222. }
  223. }
  224. #endif
  225. @end