XLFormSelectorCell.m 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. //
  2. // XLFormSelectorCell.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 "XLForm.h"
  26. #import "NSObject+XLFormAdditions.h"
  27. #import "XLFormRowDescriptor.h"
  28. #import "XLFormSelectorCell.h"
  29. #import "NSArray+XLFormAdditions.h"
  30. @interface XLFormSelectorCell() <UIActionSheetDelegate, UIPickerViewDelegate, UIPickerViewDataSource, UIPopoverControllerDelegate>
  31. @property (nonatomic) UIPickerView * pickerView;
  32. @property (nonatomic) UIPopoverController *popoverController;
  33. @end
  34. @implementation XLFormSelectorCell
  35. {
  36. UIColor * _beforeChangeColor;
  37. }
  38. -(NSString *)valueDisplayText
  39. {
  40. if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelector] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelectorPopover]){
  41. if (!self.rowDescriptor.value || [self.rowDescriptor.value count] == 0){
  42. return self.rowDescriptor.noValueDisplayText;
  43. }
  44. if (self.rowDescriptor.valueTransformer){
  45. NSAssert([self.rowDescriptor.valueTransformer isSubclassOfClass:[NSValueTransformer class]], @"valueTransformer is not a subclass of NSValueTransformer");
  46. NSValueTransformer * valueTransformer = [self.rowDescriptor.valueTransformer new];
  47. NSString * tranformedValue = [valueTransformer transformedValue:self.rowDescriptor.value];
  48. if (tranformedValue){
  49. return tranformedValue;
  50. }
  51. }
  52. NSMutableArray * descriptionArray = [NSMutableArray arrayWithCapacity:[self.rowDescriptor.value count]];
  53. for (id option in self.rowDescriptor.selectorOptions) {
  54. NSArray * selectedValues = self.rowDescriptor.value;
  55. if ([selectedValues formIndexForItem:option] != NSNotFound){
  56. if (self.rowDescriptor.valueTransformer){
  57. NSAssert([self.rowDescriptor.valueTransformer isSubclassOfClass:[NSValueTransformer class]], @"valueTransformer is not a subclass of NSValueTransformer");
  58. NSValueTransformer * valueTransformer = [self.rowDescriptor.valueTransformer new];
  59. NSString * tranformedValue = [valueTransformer transformedValue:option];
  60. if (tranformedValue){
  61. [descriptionArray addObject:tranformedValue];
  62. }
  63. }
  64. else{
  65. [descriptionArray addObject:[option displayText]];
  66. }
  67. }
  68. }
  69. return [descriptionArray componentsJoinedByString:@", "];
  70. }
  71. if (!self.rowDescriptor.value){
  72. return self.rowDescriptor.noValueDisplayText;
  73. }
  74. if (self.rowDescriptor.valueTransformer){
  75. NSAssert([self.rowDescriptor.valueTransformer isSubclassOfClass:[NSValueTransformer class]], @"valueTransformer is not a subclass of NSValueTransformer");
  76. NSValueTransformer * valueTransformer = [self.rowDescriptor.valueTransformer new];
  77. NSString * tranformedValue = [valueTransformer transformedValue:self.rowDescriptor.value];
  78. if (tranformedValue){
  79. return tranformedValue;
  80. }
  81. }
  82. return [self.rowDescriptor.value displayText];
  83. }
  84. -(UIView *)inputView
  85. {
  86. if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPickerView]){
  87. return self.pickerView;
  88. }
  89. return [super inputView];
  90. }
  91. -(BOOL)formDescriptorCellCanBecomeFirstResponder
  92. {
  93. return (!self.rowDescriptor.isDisabled && ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPickerView]));
  94. }
  95. -(BOOL)formDescriptorCellBecomeFirstResponder
  96. {
  97. return [self becomeFirstResponder];
  98. }
  99. - (BOOL)canBecomeFirstResponder
  100. {
  101. if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPickerView]){
  102. return YES;
  103. }
  104. return [super canBecomeFirstResponder];
  105. }
  106. #pragma mark - Properties
  107. -(UIPickerView *)pickerView
  108. {
  109. if (_pickerView) return _pickerView;
  110. _pickerView = [[UIPickerView alloc] init];
  111. _pickerView.delegate = self;
  112. _pickerView.dataSource = self;
  113. [_pickerView selectRow:[self selectedIndex] inComponent:0 animated:NO];
  114. return _pickerView;
  115. }
  116. #pragma mark - XLFormDescriptorCell
  117. -(void)configure
  118. {
  119. [super configure];
  120. }
  121. -(void)update
  122. {
  123. [super update];
  124. self.accessoryType = self.rowDescriptor.isDisabled || !([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPush] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelector]) ? UITableViewCellAccessoryNone : UITableViewCellAccessoryDisclosureIndicator;;
  125. self.editingAccessoryType = self.accessoryType;
  126. self.selectionStyle = self.rowDescriptor.isDisabled || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeInfo] ? UITableViewCellSelectionStyleNone : UITableViewCellSelectionStyleDefault;
  127. self.textLabel.text = [NSString stringWithFormat:@"%@%@", self.rowDescriptor.title, self.rowDescriptor.required && self.rowDescriptor.sectionDescriptor.formDescriptor.addAsteriskToRequiredRowsTitle ? @"*" : @""];
  128. self.detailTextLabel.text = [self valueDisplayText];
  129. }
  130. -(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)controller
  131. {
  132. if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPush] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover]){
  133. UIViewController * controllerToPresent = nil;
  134. if (self.rowDescriptor.action.formSegueIdentifier){
  135. [controller performSegueWithIdentifier:self.rowDescriptor.action.formSegueIdentifier sender:self.rowDescriptor];
  136. }
  137. else if (self.rowDescriptor.action.formSegueClass){
  138. UIViewController * controllerToPresent = [self controllerToPresent];
  139. NSAssert(controllerToPresent, @"either rowDescriptor.action.viewControllerClass or rowDescriptor.action.viewControllerStoryboardId or rowDescriptor.action.viewControllerNibName must be assigned");
  140. NSAssert([controllerToPresent conformsToProtocol:@protocol(XLFormRowDescriptorViewController)], @"selector view controller must conform to XLFormRowDescriptorViewController protocol");
  141. UIStoryboardSegue * segue = [[self.rowDescriptor.action.formSegueClass alloc] initWithIdentifier:self.rowDescriptor.tag source:controller destination:controllerToPresent];
  142. [controller prepareForSegue:segue sender:self.rowDescriptor];
  143. [segue perform];
  144. }
  145. else if ((controllerToPresent = [self controllerToPresent])){
  146. NSAssert([controllerToPresent conformsToProtocol:@protocol(XLFormRowDescriptorViewController)], @"rowDescriptor.action.viewControllerClass must conform to XLFormRowDescriptorViewController protocol");
  147. UIViewController<XLFormRowDescriptorViewController> *selectorViewController = (UIViewController<XLFormRowDescriptorViewController> *)controllerToPresent;
  148. selectorViewController.rowDescriptor = self.rowDescriptor;
  149. selectorViewController.title = self.rowDescriptor.selectorTitle;
  150. if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover]) {
  151. if (self.popoverController && self.popoverController.popoverVisible) {
  152. [self.popoverController dismissPopoverAnimated:NO];
  153. }
  154. self.popoverController = [[UIPopoverController alloc] initWithContentViewController:selectorViewController];
  155. self.popoverController.delegate = self;
  156. if ([selectorViewController conformsToProtocol:@protocol(XLFormRowDescriptorPopoverViewController)]){
  157. ((id<XLFormRowDescriptorPopoverViewController>)selectorViewController).popoverController = self.popoverController;
  158. }
  159. if (self.detailTextLabel.window){
  160. [self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.detailTextLabel.frame.size.width, self.detailTextLabel.frame.size.height) inView:self.detailTextLabel permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
  161. }
  162. else{
  163. [self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) inView:self permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
  164. }
  165. [controller.tableView deselectRowAtIndexPath:[controller.tableView indexPathForCell:self] animated:YES];
  166. }
  167. else {
  168. [controller.navigationController pushViewController:selectorViewController animated:YES];
  169. }
  170. }
  171. else if (self.rowDescriptor.selectorOptions){
  172. XLFormOptionsViewController * optionsViewController = [[XLFormOptionsViewController alloc] initWithStyle:UITableViewStyleGrouped titleHeaderSection:nil titleFooterSection:nil];
  173. optionsViewController.rowDescriptor = self.rowDescriptor;
  174. optionsViewController.title = self.rowDescriptor.selectorTitle;
  175. if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover]) {
  176. self.popoverController = [[UIPopoverController alloc] initWithContentViewController:optionsViewController];
  177. self.popoverController.delegate = self;
  178. optionsViewController.popoverController = self.popoverController;
  179. if (self.detailTextLabel.window){
  180. [self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.detailTextLabel.frame.size.width, self.detailTextLabel.frame.size.height) inView:self.detailTextLabel permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
  181. }
  182. else{
  183. [self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) inView:self permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
  184. }
  185. [controller.tableView deselectRowAtIndexPath:[controller.tableView indexPathForCell:self] animated:YES];
  186. } else {
  187. [controller.navigationController pushViewController:optionsViewController animated:YES];
  188. }
  189. }
  190. }
  191. else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelector] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelectorPopover])
  192. {
  193. NSAssert(self.rowDescriptor.selectorOptions, @"selectorOptions property shopuld not be nil");
  194. UIViewController * controllerToPresent = nil;
  195. XLFormOptionsViewController * optionsViewController = nil;
  196. if ((controllerToPresent = [self controllerToPresent])){
  197. optionsViewController = (XLFormOptionsViewController *)controllerToPresent;
  198. } else {
  199. optionsViewController = [[XLFormOptionsViewController alloc] initWithStyle:UITableViewStyleGrouped titleHeaderSection:nil titleFooterSection:nil];
  200. }
  201. optionsViewController.rowDescriptor = self.rowDescriptor;
  202. optionsViewController.title = self.rowDescriptor.selectorTitle;
  203. if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelectorPopover]) {
  204. self.popoverController = [[UIPopoverController alloc] initWithContentViewController:optionsViewController];
  205. self.popoverController.delegate = self;
  206. optionsViewController.popoverController = self.popoverController;
  207. if (self.detailTextLabel.window){
  208. [self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.detailTextLabel.frame.size.width, self.detailTextLabel.frame.size.height) inView:self.detailTextLabel permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
  209. }
  210. else{
  211. [self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) inView:self permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
  212. }
  213. [controller.tableView deselectRowAtIndexPath:[controller.tableView indexPathForCell:self] animated:YES];
  214. } else {
  215. [controller.navigationController pushViewController:optionsViewController animated:YES];
  216. }
  217. }
  218. else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorActionSheet]){
  219. #if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
  220. UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
  221. delegate:self
  222. cancelButtonTitle:nil
  223. destructiveButtonTitle:nil
  224. otherButtonTitles:nil];
  225. for (id option in self.rowDescriptor.selectorOptions) {
  226. [actionSheet addButtonWithTitle:[option displayText]];
  227. }
  228. actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
  229. actionSheet.tag = [self.rowDescriptor hash];
  230. [actionSheet showInView:controller.view];
  231. #else
  232. if ([UIAlertController class]) {
  233. XLFormViewController * formViewController = self.formViewController;
  234. UIAlertController * alertController = [UIAlertController alertControllerWithTitle:self.rowDescriptor.selectorTitle
  235. message:nil
  236. preferredStyle:UIAlertControllerStyleActionSheet];
  237. [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
  238. style:UIAlertActionStyleCancel
  239. handler:nil]];
  240. alertController.popoverPresentationController.sourceView = formViewController.tableView;
  241. UIView* v = (self.detailTextLabel ?: self.textLabel) ?: self.contentView;
  242. alertController.popoverPresentationController.sourceRect = [formViewController.tableView convertRect:v.frame fromView:self];
  243. __weak __typeof(self)weakSelf = self;
  244. for (id option in self.rowDescriptor.selectorOptions) {
  245. NSString *optionTitle = [option displayText];
  246. if (self.rowDescriptor.valueTransformer){
  247. NSAssert([self.rowDescriptor.valueTransformer isSubclassOfClass:[NSValueTransformer class]], @"valueTransformer is not a subclass of NSValueTransformer");
  248. NSValueTransformer * valueTransformer = [self.rowDescriptor.valueTransformer new];
  249. NSString * transformedValue = [valueTransformer transformedValue:[option valueData]];
  250. if (transformedValue) {
  251. optionTitle = transformedValue;
  252. }
  253. }
  254. [alertController addAction:[UIAlertAction actionWithTitle:optionTitle
  255. style:UIAlertActionStyleDefault
  256. handler:^(UIAlertAction *action) {
  257. [weakSelf.rowDescriptor setValue:option];
  258. [formViewController.tableView reloadData];
  259. }]];
  260. }
  261. [formViewController presentViewController:alertController animated:YES completion:nil];
  262. }
  263. #ifndef XL_APP_EXTENSIONS
  264. else{
  265. UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
  266. delegate:self
  267. cancelButtonTitle:nil
  268. destructiveButtonTitle:nil
  269. otherButtonTitles:nil];
  270. for (id option in self.rowDescriptor.selectorOptions) {
  271. [actionSheet addButtonWithTitle:[option displayText]];
  272. }
  273. actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
  274. actionSheet.tag = [self.rowDescriptor hash];
  275. [actionSheet showInView:controller.view];
  276. }
  277. #endif
  278. #endif
  279. [controller.tableView deselectRowAtIndexPath:[controller.form indexPathOfFormRow:self.rowDescriptor] animated:YES];
  280. }
  281. else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorAlertView]){
  282. #if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
  283. UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:self.rowDescriptor.selectorTitle
  284. message:nil
  285. delegate:self
  286. cancelButtonTitle:nil
  287. otherButtonTitles:nil];
  288. for (id option in self.rowDescriptor.selectorOptions) {
  289. [alertView addButtonWithTitle:[option displayText]];
  290. }
  291. alertView.cancelButtonIndex = [alertView addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
  292. alertView.tag = [self.rowDescriptor hash];
  293. [alertView show];
  294. #else
  295. if ([UIAlertController class]) {
  296. UIAlertController * alertController = [UIAlertController alertControllerWithTitle:self.rowDescriptor.selectorTitle
  297. message:nil
  298. preferredStyle:UIAlertControllerStyleAlert];
  299. __weak __typeof(self)weakSelf = self;
  300. for (id option in self.rowDescriptor.selectorOptions) {
  301. [alertController addAction:[UIAlertAction actionWithTitle:[option displayText]
  302. style:UIAlertActionStyleDefault
  303. handler:^(UIAlertAction *action) {
  304. [weakSelf.rowDescriptor setValue:option];
  305. [weakSelf.formViewController.tableView reloadData];
  306. }]];
  307. }
  308. [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
  309. style:UIAlertActionStyleCancel
  310. handler:nil]];
  311. [controller presentViewController:alertController animated:YES completion:nil];
  312. }
  313. #ifndef XL_APP_EXTENSIONS
  314. else{
  315. UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:self.rowDescriptor.selectorTitle
  316. message:nil
  317. delegate:self
  318. cancelButtonTitle:nil
  319. otherButtonTitles:nil];
  320. for (id option in self.rowDescriptor.selectorOptions) {
  321. [alertView addButtonWithTitle:[option displayText]];
  322. }
  323. alertView.cancelButtonIndex = [alertView addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
  324. alertView.tag = [self.rowDescriptor hash];
  325. [alertView show];
  326. }
  327. #endif
  328. #endif
  329. [controller.tableView deselectRowAtIndexPath:[controller.form indexPathOfFormRow:self.rowDescriptor] animated:YES];
  330. }
  331. else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPickerView]){
  332. [controller.tableView selectRowAtIndexPath:nil animated:YES scrollPosition:UITableViewScrollPositionNone];
  333. }
  334. }
  335. -(void)highlight
  336. {
  337. [super highlight];
  338. _beforeChangeColor = self.detailTextLabel.textColor;
  339. self.detailTextLabel.textColor = self.tintColor;
  340. }
  341. -(void)unhighlight
  342. {
  343. [super unhighlight];
  344. self.detailTextLabel.textColor = _beforeChangeColor;
  345. }
  346. #if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
  347. #pragma mark - UIActionSheetDelegate
  348. - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
  349. {
  350. if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorActionSheet]){
  351. if ([actionSheet cancelButtonIndex] != buttonIndex){
  352. NSString * title = [actionSheet buttonTitleAtIndex:buttonIndex];
  353. for (id option in self.rowDescriptor.selectorOptions){
  354. if ([[option displayText] isEqualToString:title]){
  355. [self.rowDescriptor setValue:option];
  356. [self.formViewController.tableView reloadData];
  357. break;
  358. }
  359. }
  360. }
  361. }
  362. }
  363. #pragma mark - UIAlertViewDelegate
  364. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
  365. {
  366. if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorAlertView]){
  367. if ([alertView cancelButtonIndex] != buttonIndex){
  368. NSString * title = [alertView buttonTitleAtIndex:buttonIndex];
  369. for (id option in self.rowDescriptor.selectorOptions){
  370. if ([[option displayText] isEqualToString:title]){
  371. [self.rowDescriptor setValue:option];
  372. [self.formViewController.tableView reloadData];
  373. break;
  374. }
  375. }
  376. }
  377. }
  378. }
  379. #endif
  380. #pragma mark - UIPickerViewDelegate
  381. - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
  382. {
  383. if (self.rowDescriptor.valueTransformer){
  384. NSAssert([self.rowDescriptor.valueTransformer isSubclassOfClass:[NSValueTransformer class]], @"valueTransformer is not a subclass of NSValueTransformer");
  385. NSValueTransformer * valueTransformer = [self.rowDescriptor.valueTransformer new];
  386. NSString * tranformedValue = [valueTransformer transformedValue:[[self.rowDescriptor.selectorOptions objectAtIndex:row] valueData]];
  387. if (tranformedValue){
  388. return tranformedValue;
  389. }
  390. }
  391. return [[self.rowDescriptor.selectorOptions objectAtIndex:row] displayText];
  392. }
  393. - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
  394. {
  395. if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPickerView]){
  396. self.rowDescriptor.value = [self.rowDescriptor.selectorOptions objectAtIndex:row];
  397. self.detailTextLabel.text = [self valueDisplayText];
  398. [self setNeedsLayout];
  399. }
  400. }
  401. #pragma mark - UIPickerViewDataSource
  402. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
  403. {
  404. return 1;
  405. }
  406. - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
  407. {
  408. return self.rowDescriptor.selectorOptions.count;
  409. }
  410. #pragma mark - Helpers
  411. -(NSInteger)selectedIndex
  412. {
  413. if (self.rowDescriptor.value){
  414. for (id option in self.rowDescriptor.selectorOptions){
  415. if ([[option valueData] isEqual:[self.rowDescriptor.value valueData]]){
  416. return [self.rowDescriptor.selectorOptions indexOfObject:option];
  417. }
  418. }
  419. }
  420. return -1;
  421. }
  422. -(UIViewController *)controllerToPresent
  423. {
  424. if (self.rowDescriptor.action.viewControllerClass){
  425. return [[self.rowDescriptor.action.viewControllerClass alloc] init];
  426. }
  427. else if ([self.rowDescriptor.action.viewControllerStoryboardId length] != 0){
  428. UIStoryboard * storyboard = [self storyboardToPresent];
  429. NSAssert(storyboard != nil, @"You must provide a storyboard when rowDescriptor.action.viewControllerStoryboardId is used");
  430. return [storyboard instantiateViewControllerWithIdentifier:self.rowDescriptor.action.viewControllerStoryboardId];
  431. }
  432. else if ([self.rowDescriptor.action.viewControllerNibName length] != 0){
  433. Class viewControllerClass = NSClassFromString(self.rowDescriptor.action.viewControllerNibName);
  434. NSAssert(viewControllerClass, @"class owner of self.rowDescriptor.action.viewControllerNibName must be equal to %@", self.rowDescriptor.action.viewControllerNibName);
  435. return [[viewControllerClass alloc] initWithNibName:self.rowDescriptor.action.viewControllerNibName bundle:nil];
  436. }
  437. return nil;
  438. }
  439. -(UIStoryboard *)storyboardToPresent
  440. {
  441. if ([self.formViewController respondsToSelector:@selector(storyboardForRow:)]){
  442. return [self.formViewController storyboardForRow:self.rowDescriptor];
  443. }
  444. if (self.formViewController.storyboard){
  445. return self.formViewController.storyboard;
  446. }
  447. return nil;
  448. }
  449. #pragma mark - UIPopoverControllerDelegate
  450. - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
  451. {
  452. [self.formViewController.tableView reloadData];
  453. }
  454. @end