8282static NSString * const kAPCBasicTableViewCellIdentifier = @" APCBasicTableViewCell" ;
8383static NSString * const kAPCRightDetailTableViewCellIdentifier = @" APCRightDetailTableViewCell" ;
8484
85+ @interface APCUserInfoViewController ()
86+ - (void ) setEditing : (BOOL ) isEditing ;
87+ @end
88+
8589@interface APCProfileViewController () <ORKTaskViewControllerDelegate>
8690
8791@property (weak , nonatomic ) IBOutlet UILabel *versionLabel;
@@ -409,7 +413,7 @@ - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(
409413 APCSegmentedTableViewCell *segmentedCell = (APCSegmentedTableViewCell *)cell;
410414 segmentedCell.delegate = self;
411415 segmentedCell.selectedSegmentIndex = segmentPickerField.selectedIndex ;
412- segmentedCell.userInteractionEnabled = segmentPickerField.editable ;
416+ segmentedCell.userInteractionEnabled = segmentPickerField.editable && self. isEditing ;
413417
414418 }
415419 else if ([field isKindOfClass: [APCTableViewSwitchItem class ]]) {
@@ -436,6 +440,14 @@ - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(
436440 return cell;
437441}
438442
443+ - (void ) setEditing : (BOOL ) isEditing
444+ {
445+ [super setEditing: isEditing];
446+
447+ // Reload the table so that all the field items and cells are in the correct state for new "isEditing" property
448+ [self .tableView reloadData ];
449+ }
450+
439451#pragma mark - Prepare Content
440452
441453- (NSArray *)prepareContent
@@ -452,15 +464,38 @@ - (NSArray *)prepareContent
452464 APCUserInfoItemType itemType = type.integerValue ;
453465
454466 switch (itemType) {
467+
455468 case kAPCUserInfoItemTypeBiologicalSex :
456469 {
457- APCTableViewItem *field = [APCTableViewItem new ];
458- field.caption = NSLocalizedStringWithDefaultValue(@" Sex" , @" APCAppCore" , APCBundle (), @" Sex" , @" " );
459- field.reuseIdentifier = kAPCDefaultTableViewCellIdentifier ;
460- field.editable = NO ;
461- field.textAlignnment = NSTextAlignmentRight;
462- field.detailText = [APCUser stringValueFromSexType: self .user.biologicalSex];
463- field.selectionStyle = self.isEditing ? UITableViewCellSelectionStyleGray : UITableViewCellSelectionStyleNone;
470+ APCTableViewItem *field = nil ;
471+
472+ // If we can edit biological sex, change the UI to be a segment control
473+ if (self.canEditBiologicalSex )
474+ {
475+ APCTableViewSegmentItem *segmentField = [APCTableViewSegmentItem new ];
476+ segmentField.style = UITableViewCellStyleValue1;
477+ segmentField.segments = [APCUser sexTypesInStringValue ];
478+ segmentField.reuseIdentifier = kAPCSegmentedTableViewCellIdentifier ;
479+
480+ if (self.user .biologicalSex ) {
481+ segmentField.selectedIndex = [APCUser stringIndexFromSexType: self .user.biologicalSex];
482+ segmentField.editable = self.canEditBiologicalSex ;
483+ } else {
484+ segmentField.editable = YES ; // make it always editable, since user hasnt provided a valid value yet
485+ }
486+ segmentField.selectionStyle = self.isEditing && field.editable ? UITableViewCellSelectionStyleGray : UITableViewCellSelectionStyleNone;
487+ field = segmentField;
488+ }
489+ else // if we cant edit sex, show a simple default table view cell
490+ {
491+ field = [APCTableViewItem new ];
492+ field.caption = NSLocalizedStringWithDefaultValue(@" Sex" , @" APCAppCore" , APCBundle (), @" Sex" , @" " );
493+ field.reuseIdentifier = kAPCDefaultTableViewCellIdentifier ;
494+ field.editable = NO ;
495+ field.textAlignnment = NSTextAlignmentRight;
496+ field.detailText = [APCUser stringValueFromSexType: self .user.biologicalSex];
497+ field.selectionStyle = UITableViewCellSelectionStyleNone;
498+ }
464499
465500 APCTableViewRow *row = [APCTableViewRow new ];
466501 row.item = field;
@@ -471,13 +506,45 @@ - (NSArray *)prepareContent
471506
472507 case kAPCUserInfoItemTypeDateOfBirth :
473508 {
474- APCTableViewItem *field = [APCTableViewItem new ];
509+ APCTableViewItem *field = nil ;
510+
511+ if (self.canEditBirthDate ) // If we can edit birthdate, change the UI to be a date picker
512+ {
513+ APCTableViewDatePickerItem *dateField = [APCTableViewDatePickerItem new ];
514+ dateField.datePickerMode = UIDatePickerModeDate;
515+ NSCalendar *gregorian = [[NSCalendar alloc ] initWithCalendarIdentifier: NSCalendarIdentifierGregorian ];
516+ NSDate *currentDate = [[NSDate date ] startOfDay ];
517+ NSDateComponents * comps = [[NSDateComponents alloc ] init ];
518+ [comps setYear: -18 ];
519+ NSDate *maxDate = [gregorian dateByAddingComponents: comps toDate: currentDate options: 0 ];
520+ dateField.maximumDate = maxDate;
521+
522+ if (self.user .birthDate ) {
523+ dateField.date = self.user .birthDate ;
524+ dateField.detailText = [dateField.date toStringWithFormat: dateField.dateFormat];
525+ dateField.editable = self.canEditBirthDate ;
526+ } else {
527+ dateField.editable = YES ; // make it always editable, since user hasnt provided a valid value yet
528+ dateField.date = nil ;
529+ dateField.detailText = @" " ;
530+ }
531+ field = dateField;
532+ }
533+ else // if we cant edit birthdate, show a simple default table view cell
534+ {
535+ field = [APCTableViewItem new ];
536+ field.editable = NO ;
537+ field.textAlignnment = NSTextAlignmentRight;
538+ field.detailText = [self .user.birthDate toStringWithFormat: NSDateDefaultDateFormat];
539+ field.selectionStyle = self.isEditing ? UITableViewCellSelectionStyleGray : UITableViewCellSelectionStyleNone;
540+ }
541+
475542 field.caption = NSLocalizedStringWithDefaultValue(@" Birthdate" , @" APCAppCore" , APCBundle (), @" Birthdate" , @" " );
543+
544+ field.style = UITableViewCellStyleValue1;
476545 field.reuseIdentifier = kAPCDefaultTableViewCellIdentifier ;
477- field.editable = NO ;
478- field.textAlignnment = NSTextAlignmentRight;
479- field.detailText = [self .user.birthDate toStringWithFormat: NSDateDefaultDateFormat];
480- field.selectionStyle = self.isEditing ? UITableViewCellSelectionStyleGray : UITableViewCellSelectionStyleNone;
546+ field.textAlignnment = NSTextAlignmentRight;
547+ field.selectionStyle = self.isEditing && field.editable ? UITableViewCellSelectionStyleGray : UITableViewCellSelectionStyleNone;
481548
482549 APCTableViewRow *row = [APCTableViewRow new ];
483550 row.item = field;
@@ -1141,7 +1208,36 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
11411208 }
11421209 }
11431210 break ;
1144-
1211+
1212+ case kAPCUserInfoItemTypeDateOfBirth :
1213+ {
1214+ if (self.canEditBirthDate )
1215+ {
1216+ APCTableViewItem *field = [self itemForIndexPath: indexPath];
1217+ // Check for if we grabbed this value from HealthKit, because if we did, it can't be edited from our app
1218+ if (![self isEditingAllowedForHealthKitProperty: HKCharacteristicTypeIdentifierDateOfBirth])
1219+ {
1220+ [self showEditingNotAllowedAlertForHealthKitProperty: HKCharacteristicTypeIdentifierDateOfBirth];
1221+ [tableView deselectRowAtIndexPath: indexPath animated: YES ];
1222+ }
1223+ // only allow to be selected if we are in edit mode
1224+ else if (self.isEditing && field.isEditable )
1225+ {
1226+ [super tableView: tableView didSelectRowAtIndexPath: indexPath];
1227+ }
1228+ // if we cant edit it, simply deselect the row
1229+ else
1230+ {
1231+ [tableView deselectRowAtIndexPath: indexPath animated: YES ];
1232+ }
1233+ }
1234+ else
1235+ {
1236+ [super tableView: tableView didSelectRowAtIndexPath: indexPath];
1237+ }
1238+ }
1239+ break ;
1240+
11451241 default :{
11461242 [super tableView: tableView didSelectRowAtIndexPath: indexPath];
11471243 }
@@ -1233,6 +1329,59 @@ - (void)pickerTableViewCell:(APCPickerTableViewCell *)cell pickerViewDidSelectIn
12331329 }
12341330}
12351331
1332+ #pragma mark APCSegmentedTableViewCellDelegate methods
1333+
1334+ - (void )segmentedTableViewCell : (APCSegmentedTableViewCell *) __unused cell
1335+ didSelectSegmentAtIndex : (NSInteger ) __unused index
1336+ {
1337+ [super segmentedTableViewCell: cell didSelectSegmentAtIndex: index];
1338+
1339+ if (self.canEditBiologicalSex &&
1340+ ![self isEditingAllowedForHealthKitProperty: HKCharacteristicTypeIdentifierBiologicalSex])
1341+ {
1342+ [self showEditingNotAllowedAlertForHealthKitProperty: HKCharacteristicTypeIdentifierBiologicalSex];
1343+ // Revert back to whatever the index was originally
1344+ cell.selectedSegmentIndex = [APCUser stringIndexFromSexType: self .user.biologicalSex];
1345+ }
1346+ }
1347+
1348+ - (void ) showEditingNotAllowedAlertForHealthKitProperty : (NSString *)healthKitPropertyIdentifier
1349+ {
1350+ if ([self .delegate respondsToSelector: @selector (editingFailedForHealthKitType: )])
1351+ {
1352+ [self .delegate editingFailedForHealthKitType: healthKitPropertyIdentifier];
1353+ }
1354+ else // Since there is no delegate, show our own alert view
1355+ {
1356+ NSString * title = NSLocalizedStringWithDefaultValue(@" Edit in Health App" , @" APCAppCore" , APCBundle (), @" Edit in Health App" , @" " );
1357+ NSString * msg = NSLocalizedStringWithDefaultValue(@" Since we are accessing this information through Health Kit, you can only change it through your device's Health App" , @" APCAppCore" , APCBundle (), @" Since we are accessing this information through Health Kit, you can only change it through your device's Health App" , @" " );
1358+ UIAlertController *alertView = [UIAlertController alertControllerWithTitle: title
1359+ message: msg
1360+ preferredStyle: UIAlertControllerStyleAlert];
1361+
1362+ UIAlertAction* okAction = [UIAlertAction actionWithTitle: NSLocalizedStringWithDefaultValue(@" Okay" , @" APCAppCore" , APCBundle (), @" Okay" , @" " ) style: UIAlertActionStyleDefault
1363+ handler: ^(UIAlertAction * __unused action) {}];
1364+
1365+ [alertView addAction: okAction];
1366+ [self presentViewController: alertView animated: YES completion: nil ];
1367+ }
1368+ }
1369+
1370+ - (BOOL ) isEditingAllowedForHealthKitProperty : (NSString *) healthKitPropertyIdentifier
1371+ {
1372+ if (healthKitPropertyIdentifier == HKCharacteristicTypeIdentifierBiologicalSex &&
1373+ [self .user hasBiologicalSexInHealthKit ])
1374+ {
1375+ return NO ;
1376+ }
1377+ else if (healthKitPropertyIdentifier == HKCharacteristicTypeIdentifierDateOfBirth &&
1378+ [self .user hasBirthDateInHealthKit ])
1379+ {
1380+ return NO ;
1381+ }
1382+ return YES ;
1383+ }
1384+
12361385#pragma mark - UIImagePickerControllerDelegate
12371386
12381387- (void ) imagePickerController : (UIImagePickerController *)picker didFinishPickingMediaWithInfo : (NSDictionary *)info
@@ -1372,6 +1521,20 @@ - (void)loadProfileValuesInModel
13721521
13731522 case kAPCSettingsItemTypeSharingOptions :
13741523 break ;
1524+
1525+ case kAPCUserInfoItemTypeDateOfBirth :
1526+ if (self.canEditBirthDate ) // otherwise default item will be used
1527+ {
1528+ self.user .birthDate = [(APCTableViewDatePickerItem *)item date ];
1529+ }
1530+ break ;
1531+
1532+ case kAPCUserInfoItemTypeBiologicalSex :
1533+ if (self.canEditBiologicalSex ) // otherwise default item will be used
1534+ {
1535+ self.user .biologicalSex = [APCUser sexTypeForIndex: ((APCTableViewSegmentItem *)item).selectedIndex];
1536+ }
1537+ break ;
13751538
13761539 default :
13771540 break ;
0 commit comments