From b2c21e05424c752880ba4d075b52938c022cf242 Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Sat, 26 Sep 2020 20:36:31 -0700 Subject: [PATCH] Adds select field with picker as TextField inputView. --- MonsterCards.xcodeproj/project.pbxproj | 20 ++- MonsterCards/Base.lproj/Main.storyboard | 39 +++++ MonsterCards/Models/Language.h | 3 +- MonsterCards/Models/Language.m | 3 +- MonsterCards/Models/Monster.m | 4 + .../Views/EditMonsterViewController.m | 99 ++++++++++- MonsterCards/Views/FormFields/MCChoice.h | 28 ++++ MonsterCards/Views/FormFields/MCChoice.m | 29 ++++ .../Views/FormFields/MCFormFieldConstants.h | 1 + .../Views/FormFields/MCFormFieldConstants.m | 1 + .../FormFields/MCSelectFieldTableViewCell.h | 28 ++++ .../FormFields/MCSelectFieldTableViewCell.m | 157 ++++++++++++++++++ 12 files changed, 402 insertions(+), 10 deletions(-) create mode 100644 MonsterCards/Views/FormFields/MCChoice.h create mode 100644 MonsterCards/Views/FormFields/MCChoice.m create mode 100644 MonsterCards/Views/FormFields/MCSelectFieldTableViewCell.h create mode 100644 MonsterCards/Views/FormFields/MCSelectFieldTableViewCell.m diff --git a/MonsterCards.xcodeproj/project.pbxproj b/MonsterCards.xcodeproj/project.pbxproj index 13c13ae..c6996f6 100644 --- a/MonsterCards.xcodeproj/project.pbxproj +++ b/MonsterCards.xcodeproj/project.pbxproj @@ -34,6 +34,8 @@ E2D3E3B0250827110052A8EC /* EditMonsterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E2D3E3AF250827110052A8EC /* EditMonsterViewController.m */; }; E2D3E3B42508C3360052A8EC /* MCShortStringFieldTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E2D3E3B32508C3360052A8EC /* MCShortStringFieldTableViewCell.m */; }; E2E25805250CC3A7002E7308 /* MonsterCards.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = E2F7248225005E89007D87ED /* MonsterCards.xcdatamodeld */; }; + E2E90AFF252015B3005241C8 /* MCSelectFieldTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E2E90AFE252015B3005241C8 /* MCSelectFieldTableViewCell.m */; }; + E2E90B0525201785005241C8 /* MCChoice.m in Sources */ = {isa = PBXBuildFile; fileRef = E2E90B0425201785005241C8 /* MCChoice.m */; }; E2ECA8F32504AC3300C1FFA5 /* SkillTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E2ECA8F22504AC3300C1FFA5 /* SkillTests.m */; }; E2ECA8F52504BAAD00C1FFA5 /* MonsterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E2ECA8F42504BAAD00C1FFA5 /* MonsterTests.m */; }; E2F7247525005E89007D87ED /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E2F7247425005E89007D87ED /* AppDelegate.m */; }; @@ -122,6 +124,10 @@ E2D3E3AF250827110052A8EC /* EditMonsterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EditMonsterViewController.m; sourceTree = ""; }; E2D3E3B22508C3360052A8EC /* MCShortStringFieldTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCShortStringFieldTableViewCell.h; sourceTree = ""; }; E2D3E3B32508C3360052A8EC /* MCShortStringFieldTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MCShortStringFieldTableViewCell.m; sourceTree = ""; }; + E2E90AFD252015B3005241C8 /* MCSelectFieldTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCSelectFieldTableViewCell.h; sourceTree = ""; }; + E2E90AFE252015B3005241C8 /* MCSelectFieldTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MCSelectFieldTableViewCell.m; sourceTree = ""; }; + E2E90B0325201785005241C8 /* MCChoice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCChoice.h; sourceTree = ""; }; + E2E90B0425201785005241C8 /* MCChoice.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MCChoice.m; sourceTree = ""; }; E2ECA8F22504AC3300C1FFA5 /* SkillTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SkillTests.m; sourceTree = ""; }; E2ECA8F42504BAAD00C1FFA5 /* MonsterTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MonsterTests.m; sourceTree = ""; }; E2F7247025005E89007D87ED /* Monster Cards.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Monster Cards.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -276,12 +282,16 @@ E2591EB62509DD4900B396FD /* MCFormFieldDelegate.h */, E288744E25148BAD005CA948 /* MCFormFieldConstants.h */, E288744925148BA0005CA948 /* MCFormFieldConstants.m */, - E20C315225146708003AB1AA /* MCIntegerFieldTableViewCell.h */, - E20C315325146708003AB1AA /* MCIntegerFieldTableViewCell.m */, - E2D3E3B22508C3360052A8EC /* MCShortStringFieldTableViewCell.h */, - E2D3E3B32508C3360052A8EC /* MCShortStringFieldTableViewCell.m */, + E2E90B0325201785005241C8 /* MCChoice.h */, + E2E90B0425201785005241C8 /* MCChoice.m */, E2805512251E03BE00C87527 /* MCBooleanFieldTableViewCell.h */, E2805513251E03BE00C87527 /* MCBooleanFieldTableViewCell.m */, + E20C315225146708003AB1AA /* MCIntegerFieldTableViewCell.h */, + E20C315325146708003AB1AA /* MCIntegerFieldTableViewCell.m */, + E2E90AFD252015B3005241C8 /* MCSelectFieldTableViewCell.h */, + E2E90AFE252015B3005241C8 /* MCSelectFieldTableViewCell.m */, + E2D3E3B22508C3360052A8EC /* MCShortStringFieldTableViewCell.h */, + E2D3E3B32508C3360052A8EC /* MCShortStringFieldTableViewCell.m */, ); path = FormFields; sourceTree = ""; @@ -623,10 +633,12 @@ E25BD5F8250368A8007B04EF /* SavingThrow.m in Sources */, E2F7248C25005E8A007D87ED /* main.m in Sources */, E25BD5FB250369D7007B04EF /* Skill.m in Sources */, + E2E90B0525201785005241C8 /* MCChoice.m in Sources */, E2F7247825005E89007D87ED /* SceneDelegate.m in Sources */, E20D032425031B9D00FB6E43 /* SearchViewController.m in Sources */, E22F837C2511D14E0072105C /* JSONHelper.m in Sources */, E25BD60125036BF8007B04EF /* Language.m in Sources */, + E2E90AFF252015B3005241C8 /* MCSelectFieldTableViewCell.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MonsterCards/Base.lproj/Main.storyboard b/MonsterCards/Base.lproj/Main.storyboard index 063036d..e23a09a 100644 --- a/MonsterCards/Base.lproj/Main.storyboard +++ b/MonsterCards/Base.lproj/Main.storyboard @@ -394,6 +394,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MonsterCards/Models/Language.h b/MonsterCards/Models/Language.h index 2b5c5f4..fdc6939 100644 --- a/MonsterCards/Models/Language.h +++ b/MonsterCards/Models/Language.h @@ -15,7 +15,8 @@ NS_ASSUME_NONNULL_BEGIN @property NSString* name; @property BOOL speaks; --(id)initWithName: (NSString*)name andSpeaks: (BOOL)canSpeak; +-(id)initWithName:(NSString*)name + andSpeaks:(BOOL)canSpeak; @end diff --git a/MonsterCards/Models/Language.m b/MonsterCards/Models/Language.m index a903b99..fdda235 100644 --- a/MonsterCards/Models/Language.m +++ b/MonsterCards/Models/Language.m @@ -19,7 +19,8 @@ return self; } --(id)initWithName: (NSString*)name andSpeaks: (BOOL)canSpeak { +-(id)initWithName:(NSString*)name + andSpeaks:(BOOL)canSpeak { self = [super init]; self.name = name; diff --git a/MonsterCards/Models/Monster.m b/MonsterCards/Models/Monster.m index 3215174..64d47e7 100644 --- a/MonsterCards/Models/Monster.m +++ b/MonsterCards/Models/Monster.m @@ -504,6 +504,10 @@ NSString* const kMonsterSizeGargantuan = @"gargantuan"; self.swimSpeed = monster.swimSpeed; self.hasCustomSpeed = monster.hasCustomSpeed; self.customSpeed = monster.customSpeed; + self.armorType = monster.armorType; + self.naturalArmorBonus = monster.naturalArmorBonus; + self.hasShield = monster.hasShield; + self.customArmor = monster.customArmor; } @end diff --git a/MonsterCards/Views/EditMonsterViewController.m b/MonsterCards/Views/EditMonsterViewController.m index 2b9c0e5..a99d4ea 100644 --- a/MonsterCards/Views/EditMonsterViewController.m +++ b/MonsterCards/Views/EditMonsterViewController.m @@ -7,9 +7,10 @@ // #import "EditMonsterViewController.h" -#import "MCShortStringFieldTableViewCell.h" -#import "MCIntegerFieldTableViewCell.h" #import "MCBooleanFieldTableViewCell.h" +#import "MCIntegerFieldTableViewCell.h" +#import "MCSelectFieldTableViewCell.h" +#import "MCShortStringFieldTableViewCell.h" #import "AppDelegate.h" @interface EditMonsterViewController () @@ -55,12 +56,48 @@ const int kAbilityScoreSectionRowIndexCharisma = 5; @implementation EditMonsterViewController { NSManagedObjectContext *_context; + NSArray* _armorTypes; } - (void)viewDidLoad { [super viewDidLoad]; AppDelegate *appDelegate = (AppDelegate*)UIApplication.sharedApplication.delegate; _context = appDelegate.persistentContainer.viewContext; + + _armorTypes = [NSArray arrayWithObjects: + [MCChoice choiceWithLabel:NSLocalizedString(@"None", @"") + andValue:kArmorNameNone], + [MCChoice choiceWithLabel:NSLocalizedString(@"Natural Armor", @"") + andValue:kArmorNameNaturalArmor], + [MCChoice choiceWithLabel:NSLocalizedString(@"Mage Armor", @"") + andValue:kArmorNameMageArmor], + [MCChoice choiceWithLabel:NSLocalizedString(@"Padded", @"") + andValue:kArmorNamePadded], + [MCChoice choiceWithLabel:NSLocalizedString(@"Leather", @"") + andValue:kArmorNameLeather], + [MCChoice choiceWithLabel:NSLocalizedString(@"Studded", @"") + andValue:kArmorNameStuddedLeather], + [MCChoice choiceWithLabel:NSLocalizedString(@"Hide", @"") + andValue:kArmorNameHide], + [MCChoice choiceWithLabel:NSLocalizedString(@"Chain Shirt", @"") + andValue:kArmorNameChainShirt], + [MCChoice choiceWithLabel:NSLocalizedString(@"Scale Mail", @"") + andValue:kArmorNameScaleMail], + [MCChoice choiceWithLabel:NSLocalizedString(@"Breastplate", @"") + andValue:kArmorNameBreastplate], + [MCChoice choiceWithLabel:NSLocalizedString(@"Half Plate", @"") + andValue:kArmorNameHalfPlate], + [MCChoice choiceWithLabel:NSLocalizedString(@"Ring Mail", @"") + andValue:kArmorNameRingMail], + [MCChoice choiceWithLabel:NSLocalizedString(@"Chain Mail", @"") + andValue:kArmorNameChainMail], + [MCChoice choiceWithLabel:NSLocalizedString(@"Splint", @"") + andValue:kArmorNameSplintMail], + [MCChoice choiceWithLabel:NSLocalizedString(@"Plate", @"") + andValue:kArmorNamePlateMail], + [MCChoice choiceWithLabel:NSLocalizedString(@"Other", @"") + andValue:kArmorNameOther], + nil]; self.monsterTableView.dataSource = self; self.monsterTableView.delegate = self; @@ -131,6 +168,24 @@ const int kAbilityScoreSectionRowIndexCharisma = 5; return cell; } +- (MCSelectFieldTableViewCell*) makeSelectCellFromTableView:(UITableView*)tableView + withIdentifier:(NSString*)identifier + label:(NSString*)label + initialValue:(NSObject*)initialValue + andChoices:(NSArray*)choices { + MCSelectFieldTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MCSelectField"]; + if (!cell || ![cell isKindOfClass:[MCSelectFieldTableViewCell class]]) { + return nil; + } + cell.delegate = self; + cell.identifier = identifier; + cell.label = label; + cell.selectedValue = initialValue; + cell.choices = choices; + + return cell; +} + #pragma mark - Navigation @@ -160,7 +215,7 @@ const int kAbilityScoreSectionRowIndexCharisma = 5; // * Alignment return 8; case kSectionIndexArmor: - return 0; + return 4; case kSectionIndexSpeed: return 8; case kSectionIndexAbilityScores: @@ -181,7 +236,7 @@ titleForHeaderInSection:(NSInteger)section { case kSectionIndexBasicInfo: return NSLocalizedString(@"Basic Info", @"Section title"); case kSectionIndexArmor: - return NSLocalizedString(@"Armor and HP", @"Section title"); + return NSLocalizedString(@"Armor", @"Section title"); case kSectionIndexSpeed: return NSLocalizedString(@"Speed", @"Section title"); case kSectionIndexAbilityScores: @@ -250,6 +305,31 @@ titleForHeaderInSection:(NSInteger)section { break; case kSectionIndexArmor: switch (indexPath.row) { + case kArmorSectionRowIndexArmorType: + newCell = [self makeSelectCellFromTableView:self.monsterTableView + withIdentifier:@"monster.armorType" + label:NSLocalizedString(@"Type", @"") + initialValue:self.editingMonster.armorType + andChoices:_armorTypes]; + break; + case kArmorSectionRowIndexHasShield: + newCell = [self makeBooleanCellFromTableView:self.monsterTableView + withIdentifier:@"monster.hasShield" + label:NSLocalizedString(@"Shield", @"") + andInitialValue:self.editingMonster.hasShield]; + break; + case kArmorSectionRowIndexCustomArmor: + newCell = [self makeShortStringCellFromTableView:self.monsterTableView + withIdentifier:@"monster.customArmor" + label:NSLocalizedString(@"Custom Armor", @"") + andInitialValue:self.editingMonster.customArmor]; + break; + case kArmorSectionRowIndexNaturalArmorBonus: + newCell = [self makeIntegerCellFromTableView:self.monsterTableView + withIdentifier:@"monster.naturalArmorBonus" + label:NSLocalizedString(@"Natural Armor Bonus", @"") + andInitialValue:self.editingMonster.naturalArmorBonus]; + break; } break; case kSectionIndexSpeed: @@ -373,6 +453,8 @@ titleForHeaderInSection:(NSInteger)section { self.editingMonster.hpText = (NSString*)value; } else if ([@"monster.customSpeed" isEqualToString:identifier]) { self.editingMonster.customSpeed = (NSString*)value; + } else if ([@"monster.customArmor" isEqualToString:identifier]) { + self.editingMonster.customArmor = (NSString*)value; } } if ([kMCFieldValueTypeInteger isEqualToString:type]) { @@ -400,6 +482,8 @@ titleForHeaderInSection:(NSInteger)section { self.editingMonster.flySpeed = [(NSNumber*)value intValue]; } else if ([@"monster.swimSpeed" isEqualToString:identifier]) { self.editingMonster.swimSpeed = [(NSNumber*)value intValue]; + } else if ([@"monster.naturalArmorBonus" isEqualToString:identifier]) { + self.editingMonster.naturalArmorBonus = [(NSNumber*)value intValue]; } } if ([kMCFieldValueTypeBoolean isEqualToString:type]) { @@ -409,6 +493,13 @@ titleForHeaderInSection:(NSInteger)section { self.editingMonster.canHover = [(NSNumber*)value boolValue]; } else if ([@"monster.hasCustomSpeed" isEqualToString:identifier]) { self.editingMonster.hasCustomSpeed = [(NSNumber*)value boolValue]; + } else if ([@"monster.hasShield" isEqualToString:identifier]) { + self.editingMonster.hasShield = [(NSNumber*)value boolValue]; + } + } + if ([kMCFieldValueTypeChoice isEqualToString:type]) { + if ([@"monster.armorType" isEqualToString:identifier]) { + self.editingMonster.armorType = (NSString*)value; } } } diff --git a/MonsterCards/Views/FormFields/MCChoice.h b/MonsterCards/Views/FormFields/MCChoice.h new file mode 100644 index 0000000..14f3045 --- /dev/null +++ b/MonsterCards/Views/FormFields/MCChoice.h @@ -0,0 +1,28 @@ +// +// MCChoice.h +// MonsterCards +// +// Created by Tom Hicks on 9/26/20. +// Copyright © 2020 Tom Hicks. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MCChoice : NSObject + +@property NSString* label; +@property NSObject* value; + ++(id)choiceWithLabel:(NSString*)label + andValue:(NSObject*)value; + +-(id)initWithLabel:(NSString*)label + andValue:(NSObject*)value; + + + +@end + +NS_ASSUME_NONNULL_END diff --git a/MonsterCards/Views/FormFields/MCChoice.m b/MonsterCards/Views/FormFields/MCChoice.m new file mode 100644 index 0000000..f8aea27 --- /dev/null +++ b/MonsterCards/Views/FormFields/MCChoice.m @@ -0,0 +1,29 @@ +// +// MCChoice.m +// MonsterCards +// +// Created by Tom Hicks on 9/26/20. +// Copyright © 2020 Tom Hicks. All rights reserved. +// + +#import "MCChoice.h" + +@implementation MCChoice + ++(id)choiceWithLabel:(NSString*)label + andValue:(NSObject*)value { + return [[MCChoice alloc] initWithLabel:label + andValue:value]; +} + +-(id)initWithLabel:(NSString*)label + andValue:(NSObject*)value { + self = [super init]; + + self.label = label; + self.value = value; + + return self; +} + +@end diff --git a/MonsterCards/Views/FormFields/MCFormFieldConstants.h b/MonsterCards/Views/FormFields/MCFormFieldConstants.h index c8e9a9e..a2afed3 100644 --- a/MonsterCards/Views/FormFields/MCFormFieldConstants.h +++ b/MonsterCards/Views/FormFields/MCFormFieldConstants.h @@ -12,5 +12,6 @@ extern NSString* const kMCFieldValueTypeInteger; extern NSString* const kMCFieldValueTypeString; extern NSString* const kMCFieldValueTypeBoolean; +extern NSString* const kMCFieldValueTypeChoice; #endif /* MCFormFieldConstants_h */ diff --git a/MonsterCards/Views/FormFields/MCFormFieldConstants.m b/MonsterCards/Views/FormFields/MCFormFieldConstants.m index f2baa11..b7266cf 100644 --- a/MonsterCards/Views/FormFields/MCFormFieldConstants.m +++ b/MonsterCards/Views/FormFields/MCFormFieldConstants.m @@ -12,3 +12,4 @@ NSString* const kMCFieldValueTypeInteger = @"Integer"; NSString* const kMCFieldValueTypeString = @"String"; NSString* const kMCFieldValueTypeBoolean = @"Boolean"; +NSString* const kMCFieldValueTypeChoice = @"Choice"; diff --git a/MonsterCards/Views/FormFields/MCSelectFieldTableViewCell.h b/MonsterCards/Views/FormFields/MCSelectFieldTableViewCell.h new file mode 100644 index 0000000..8d89ef6 --- /dev/null +++ b/MonsterCards/Views/FormFields/MCSelectFieldTableViewCell.h @@ -0,0 +1,28 @@ +// +// MCSelectFieldTableViewCell.h +// MonsterCards +// +// Created by Tom Hicks on 9/26/20. +// Copyright © 2020 Tom Hicks. All rights reserved. +// + +#import +#import "MCFormFieldDelegate.h" +#import "MCChoice.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MCSelectFieldTableViewCell : UITableViewCell + +@property NSString* identifier; +@property NSString* label; +@property NSObject* selectedValue; +@property NSArray* choices; + +@property (weak, nonatomic) id delegate; +@property (weak, nonatomic) IBOutlet UITextField *textField; +@property (weak, nonatomic) IBOutlet UILabel *labelView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MonsterCards/Views/FormFields/MCSelectFieldTableViewCell.m b/MonsterCards/Views/FormFields/MCSelectFieldTableViewCell.m new file mode 100644 index 0000000..fe52804 --- /dev/null +++ b/MonsterCards/Views/FormFields/MCSelectFieldTableViewCell.m @@ -0,0 +1,157 @@ +// +// MCSelectFieldTableViewCell.m +// MonsterCards +// +// Created by Tom Hicks on 9/26/20. +// Copyright © 2020 Tom Hicks. All rights reserved. +// + +#import "MCSelectFieldTableViewCell.h" + +@implementation MCSelectFieldTableViewCell { + MCChoice* _selectedChoice; +} + +@synthesize choices = _choices; +-(void)setChoices:(NSArray*)choices { + // TODO: only do this if choices is different + // TODO: update selectedValue and selectedIndex + _choices = choices; + + if (![_choices isEqualToArray:choices]) { + self.selectedValue = _selectedValue; + } else if (choices) { + self.selectedValue = [choices firstObject].value; + } +} +-(NSArray*)choices { + return _choices; +} + +@synthesize identifier = _identifier; +-(void)setIdentifier:(NSString*)identifier { + if (![_identifier isEqualToString:identifier]) { + _identifier = identifier; + } +} +-(NSString*)identifier { + return _identifier; +} + +@synthesize label = _label; +-(void)setLabel:(NSString*)label { + if (![_label isEqualToString:label]) { + _label = label; + } + if (_labelView && ![_labelView.text isEqualToString:label]) { + _labelView.text = label; + } +} +-(NSString*)label { + return _label; +} + +-(MCChoice*)findChoiceWithValue:(NSObject*)value + inArray:(NSArray*)array { + NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id element, NSDictionary *bindings) { + if (![element isKindOfClass:[MCChoice class]]) { + return NO; + } + MCChoice *choice = (MCChoice*)element; + return [choice.value isEqual:value]; + }]; + NSArray *matchingChoices = [_choices filteredArrayUsingPredicate:predicate]; + MCChoice *foundChoice = matchingChoices.count > 0 ? matchingChoices.firstObject : nil; + return foundChoice; +} + +@synthesize selectedValue = _selectedValue; +-(void)setSelectedValue:(NSObject*)value { + if (!_choices) { + // choices hasn't been initialized yet so just set our selected value until choices is set + _selectedValue = value; + } + MCChoice *foundChoice = [self findChoiceWithValue:value + inArray:_choices]; + if (![_selectedChoice isEqual:foundChoice] || ![_selectedValue isEqual:foundChoice.value]) { + _selectedChoice = foundChoice; + _selectedValue = foundChoice.value; + if (_delegate) { + [_delegate editableValueDidChange:_selectedValue + forIdentifier:_identifier + andType:kMCFieldValueTypeChoice]; + } + } + self.textField.text = _selectedChoice != nil + ? _selectedChoice.label != nil + ? _selectedChoice.label + : @"" + : @""; +} +-(NSObject*)selectedValue { + return _selectedValue; +} + +- (void)awakeFromNib { + [super awakeFromNib]; + UIPickerView *childPicker = [[UIPickerView alloc] init]; + childPicker.delegate = self; + childPicker.dataSource = self; + self.textField.inputView = childPicker; + + UIToolbar *toolbar = [[UIToolbar alloc] init]; + [toolbar sizeToFit]; + + UIBarButtonItem *button = + [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Done", @"Button label") + style:UIBarButtonItemStylePlain + target:self + action:@selector(choiceSelected)]; + [toolbar setItems:@[button] + animated:true]; + [toolbar setUserInteractionEnabled:YES]; + self.textField.inputAccessoryView = toolbar; + self.textField.hidden = NO; + self.textField.text = _selectedChoice.label; + self.textField.delegate = self; +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +- (void)choiceSelected { + [self endEditing:true]; +} + +#pragma mark - UIPickerViewDataSource + +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { + return 1; +} + +- (NSInteger)pickerView:(UIPickerView *)pickerView +numberOfRowsInComponent:(NSInteger)component { + return [_choices count]; +} + +#pragma mark - UIPickerViewDelegate + +- (NSString *)pickerView:(UIPickerView *)pickerView + titleForRow:(NSInteger)row + forComponent:(NSInteger)component { + return [_choices objectAtIndex:row].label; +} + +- (void)pickerView:(UIPickerView *)pickerView + didSelectRow:(NSInteger)row + inComponent:(NSInteger)component { + + _selectedChoice = [_choices objectAtIndex:row]; + self.textField.text = _selectedChoice.label; + self.selectedValue = _selectedChoice.value; +} + +@end