Adds Saving Throws to the data model and monster editor.
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
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 */; };
|
||||
E2E90B172520667F005241C8 /* MCRadioFieldTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E2E90B162520667E005241C8 /* MCRadioFieldTableViewCell.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 */; };
|
||||
@@ -128,6 +129,8 @@
|
||||
E2E90AFE252015B3005241C8 /* MCSelectFieldTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MCSelectFieldTableViewCell.m; sourceTree = "<group>"; };
|
||||
E2E90B0325201785005241C8 /* MCChoice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCChoice.h; sourceTree = "<group>"; };
|
||||
E2E90B0425201785005241C8 /* MCChoice.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MCChoice.m; sourceTree = "<group>"; };
|
||||
E2E90B152520667E005241C8 /* MCRadioFieldTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCRadioFieldTableViewCell.h; sourceTree = "<group>"; };
|
||||
E2E90B162520667E005241C8 /* MCRadioFieldTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MCRadioFieldTableViewCell.m; sourceTree = "<group>"; };
|
||||
E2ECA8F22504AC3300C1FFA5 /* SkillTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SkillTests.m; sourceTree = "<group>"; };
|
||||
E2ECA8F42504BAAD00C1FFA5 /* MonsterTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MonsterTests.m; sourceTree = "<group>"; };
|
||||
E2F7247025005E89007D87ED /* Monster Cards.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Monster Cards.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -288,6 +291,8 @@
|
||||
E2805513251E03BE00C87527 /* MCBooleanFieldTableViewCell.m */,
|
||||
E20C315225146708003AB1AA /* MCIntegerFieldTableViewCell.h */,
|
||||
E20C315325146708003AB1AA /* MCIntegerFieldTableViewCell.m */,
|
||||
E2E90B152520667E005241C8 /* MCRadioFieldTableViewCell.h */,
|
||||
E2E90B162520667E005241C8 /* MCRadioFieldTableViewCell.m */,
|
||||
E2E90AFD252015B3005241C8 /* MCSelectFieldTableViewCell.h */,
|
||||
E2E90AFE252015B3005241C8 /* MCSelectFieldTableViewCell.m */,
|
||||
E2D3E3B22508C3360052A8EC /* MCShortStringFieldTableViewCell.h */,
|
||||
@@ -635,6 +640,7 @@
|
||||
E25BD5FB250369D7007B04EF /* Skill.m in Sources */,
|
||||
E2E90B0525201785005241C8 /* MCChoice.m in Sources */,
|
||||
E2F7247825005E89007D87ED /* SceneDelegate.m in Sources */,
|
||||
E2E90B172520667F005241C8 /* MCRadioFieldTableViewCell.m in Sources */,
|
||||
E20D032425031B9D00FB6E43 /* SearchViewController.m in Sources */,
|
||||
E22F837C2511D14E0072105C /* JSONHelper.m in Sources */,
|
||||
E25BD60125036BF8007B04EF /* Language.m in Sources */,
|
||||
|
||||
@@ -408,15 +408,71 @@
|
||||
<rect key="frame" x="0.0" y="88" width="414" height="725"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="MCIntegerField" id="KwC-8P-1dy" userLabel="MCIntegerField" customClass="MCIntegerFieldTableViewCell">
|
||||
<rect key="frame" x="0.0" y="28" width="414" height="43.5"/>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="MCRadioField" id="iSG-Tv-aCX" userLabel="MCRadioField" customClass="MCRadioFieldTableViewCell">
|
||||
<rect key="frame" x="0.0" y="28" width="414" height="68"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="KwC-8P-1dy" id="Dwe-Tg-VQ6">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.5"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="iSG-Tv-aCX" id="scU-nK-qiI">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="68"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="RCc-cF-BI3" userLabel="Text Field">
|
||||
<rect key="frame" x="82" y="5" width="192" height="34"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="nTa-ey-RFM">
|
||||
<rect key="frame" x="20" y="8" width="374" height="52"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="clip" baselineAdjustment="alignBaselines" minimumScaleFactor="0.25" translatesAutoresizingMaskIntoConstraints="NO" id="Sap-Qr-1ZU">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="rJq-eZ-wvm">
|
||||
<rect key="frame" x="0.0" y="21" width="374" height="32"/>
|
||||
<segments>
|
||||
<segment title="First"/>
|
||||
<segment title="Second"/>
|
||||
</segments>
|
||||
<connections>
|
||||
<action selector="selectedSegmentChanged:" destination="iSG-Tv-aCX" eventType="valueChanged" id="k8p-F7-ILf"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="nTa-ey-RFM" firstAttribute="top" secondItem="scU-nK-qiI" secondAttribute="top" constant="8" id="VT0-G5-ofZ"/>
|
||||
<constraint firstAttribute="bottom" secondItem="nTa-ey-RFM" secondAttribute="bottom" constant="8" id="XR5-nT-N05"/>
|
||||
<constraint firstItem="nTa-ey-RFM" firstAttribute="leading" secondItem="scU-nK-qiI" secondAttribute="leading" constant="20" id="oB6-ry-kjt"/>
|
||||
<constraint firstAttribute="trailing" secondItem="nTa-ey-RFM" secondAttribute="trailing" constant="20" id="p7Q-Bn-sSi"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<outlet property="labelView" destination="Sap-Qr-1ZU" id="qJ3-Wb-qrb"/>
|
||||
<outlet property="segmentedControl" destination="rJq-eZ-wvm" id="gKh-IH-iQO"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="MCIntegerField" id="KwC-8P-1dy" userLabel="MCIntegerField" customClass="MCIntegerFieldTableViewCell">
|
||||
<rect key="frame" x="0.0" y="96" width="414" height="71.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="KwC-8P-1dy" id="Dwe-Tg-VQ6">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="71.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="tqg-e0-rNO">
|
||||
<rect key="frame" x="20" y="8" width="374" height="55.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="clip" baselineAdjustment="alignBaselines" minimumScaleFactor="0.25" translatesAutoresizingMaskIntoConstraints="NO" id="7nN-Bo-Jgm">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="21" id="x72-wj-jT3"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5Hz-MY-MYZ">
|
||||
<rect key="frame" x="0.0" y="21" width="374" height="34.5"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="10" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="RCc-cF-BI3" userLabel="Text Field">
|
||||
<rect key="frame" x="0.0" y="0.0" width="280" height="34.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="34" id="8Nj-FL-Ab6"/>
|
||||
</constraints>
|
||||
@@ -427,33 +483,24 @@
|
||||
</connections>
|
||||
</textField>
|
||||
<stepper opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" maximumValue="100" translatesAutoresizingMaskIntoConstraints="NO" id="vgc-Rg-Zc8">
|
||||
<rect key="frame" x="294" y="6" width="100" height="32"/>
|
||||
<rect key="frame" x="280" y="0.0" width="94" height="34.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="32" id="HhX-Qt-vVP"/>
|
||||
<constraint firstAttribute="width" constant="100" id="Qn1-ca-Tsy"/>
|
||||
<constraint firstAttribute="height" constant="34" id="HhX-Qt-vVP"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="stepperValueChanged:" destination="KwC-8P-1dy" eventType="valueChanged" id="BKh-dh-f3d"/>
|
||||
</connections>
|
||||
</stepper>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7nN-Bo-Jgm">
|
||||
<rect key="frame" x="20" y="11.5" width="42" height="21"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="21" id="x72-wj-jT3"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="vgc-Rg-Zc8" firstAttribute="centerY" secondItem="Dwe-Tg-VQ6" secondAttribute="centerY" id="6as-ZA-8B4"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="vgc-Rg-Zc8" secondAttribute="trailing" id="GHC-1H-v20"/>
|
||||
<constraint firstItem="7nN-Bo-Jgm" firstAttribute="centerY" secondItem="Dwe-Tg-VQ6" secondAttribute="centerY" id="Rcx-L4-hEN"/>
|
||||
<constraint firstItem="7nN-Bo-Jgm" firstAttribute="leading" secondItem="Dwe-Tg-VQ6" secondAttribute="leadingMargin" id="SQY-8s-eLf"/>
|
||||
<constraint firstItem="RCc-cF-BI3" firstAttribute="leading" secondItem="7nN-Bo-Jgm" secondAttribute="trailing" constant="20" id="So8-Uf-Zfa"/>
|
||||
<constraint firstItem="vgc-Rg-Zc8" firstAttribute="leading" secondItem="RCc-cF-BI3" secondAttribute="trailing" constant="20" id="T1Y-Pj-gsO"/>
|
||||
<constraint firstItem="RCc-cF-BI3" firstAttribute="centerY" secondItem="Dwe-Tg-VQ6" secondAttribute="centerY" id="ett-1I-J0L"/>
|
||||
<constraint firstAttribute="trailing" secondItem="tqg-e0-rNO" secondAttribute="trailing" constant="20" id="9U8-8r-ZOV"/>
|
||||
<constraint firstItem="tqg-e0-rNO" firstAttribute="top" secondItem="Dwe-Tg-VQ6" secondAttribute="top" constant="8" id="Ctm-x1-7Uf"/>
|
||||
<constraint firstAttribute="bottom" secondItem="tqg-e0-rNO" secondAttribute="bottom" constant="8" id="gHo-d9-oh1"/>
|
||||
<constraint firstItem="tqg-e0-rNO" firstAttribute="leading" secondItem="Dwe-Tg-VQ6" secondAttribute="leading" constant="20" id="pSJ-yP-eoc"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
@@ -463,7 +510,7 @@
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="MCShortStringField" id="s66-ds-RzY" userLabel="MCShortStringField" customClass="MCShortStringFieldTableViewCell">
|
||||
<rect key="frame" x="0.0" y="71.5" width="414" height="43.5"/>
|
||||
<rect key="frame" x="0.0" y="167.5" width="414" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="s66-ds-RzY" id="hip-Sr-WMn">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.5"/>
|
||||
@@ -493,14 +540,14 @@
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="MCBooleanField" id="aNO-fN-IMT" userLabel="MCBooleanField" customClass="MCBooleanFieldTableViewCell">
|
||||
<rect key="frame" x="0.0" y="115" width="414" height="43.5"/>
|
||||
<rect key="frame" x="0.0" y="211" width="414" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="aNO-fN-IMT" id="S88-r0-N1u">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tsg-zB-HOv">
|
||||
<rect key="frame" x="20" y="11.5" width="305" height="21"/>
|
||||
<rect key="frame" x="20" y="11.5" width="305" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -529,14 +576,14 @@
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="MCSelectField" id="PQF-mC-UlI" userLabel="MCSelectField" customClass="MCSelectFieldTableViewCell">
|
||||
<rect key="frame" x="0.0" y="158.5" width="414" height="37.5"/>
|
||||
<rect key="frame" x="0.0" y="254.5" width="414" height="37.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="PQF-mC-UlI" id="Wcu-Sa-z2O">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="37.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lik-sI-94j" userLabel="Label View">
|
||||
<rect key="frame" x="20" y="8" width="42" height="21.5"/>
|
||||
<rect key="frame" x="20" y="8" width="41.5" height="21.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="21" id="A1K-Wk-Nuf"/>
|
||||
</constraints>
|
||||
@@ -545,7 +592,7 @@
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="DFa-Hd-laX" userLabel="Text Field">
|
||||
<rect key="frame" x="82" y="2" width="312" height="34"/>
|
||||
<rect key="frame" x="81.5" y="2" width="312.5" height="34"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="34" id="zHt-9x-mSt"/>
|
||||
</constraints>
|
||||
|
||||
@@ -56,6 +56,14 @@ extern NSString* const kArmorNameSplintMail;
|
||||
extern NSString* const kArmorNamePlateMail;
|
||||
extern NSString* const kArmorNameOther;
|
||||
|
||||
extern NSString *const kProficiencyTypeNone;
|
||||
extern NSString *const kProficiencyTypeProficient;
|
||||
extern NSString *const kProficiencyTypeExpertise;
|
||||
|
||||
extern NSString *const kAdvantageTypeNone;
|
||||
extern NSString *const kAdvantageTypeAdvantage;
|
||||
extern NSString *const kAdvantageTypeDisadvantage;
|
||||
|
||||
@class Skill;
|
||||
|
||||
@interface Monster : NSManagedObject
|
||||
|
||||
@@ -63,6 +63,14 @@ NSString* const kMonsterSizeLarge = @"large";
|
||||
NSString* const kMonsterSizeHuge = @"huge";
|
||||
NSString* const kMonsterSizeGargantuan = @"gargantuan";
|
||||
|
||||
NSString *const kProficiencyTypeNone = @"none";
|
||||
NSString *const kProficiencyTypeProficient = @"proficient";
|
||||
NSString *const kProficiencyTypeExpertise = @"expertise";
|
||||
|
||||
NSString *const kAdvantageTypeNone = @"none";
|
||||
NSString *const kAdvantageTypeAdvantage = @"advantage";
|
||||
NSString *const kAdvantageTypeDisadvantage = @"disadvantage";
|
||||
|
||||
+(int)abilityModifierForScore: (int)score {
|
||||
return (int)floor((score - 10) / 2.0);
|
||||
}
|
||||
@@ -509,6 +517,18 @@ NSString* const kMonsterSizeGargantuan = @"gargantuan";
|
||||
self.naturalArmorBonus = monster.naturalArmorBonus;
|
||||
self.hasShield = monster.hasShield;
|
||||
self.customArmor = monster.customArmor;
|
||||
self.strengthSavingThrowAdvantage = monster.strengthSavingThrowAdvantage;
|
||||
self.strengthSavingThrowProficiency = monster.strengthSavingThrowProficiency;
|
||||
self.dexteritySavingThrowAdvantage = monster.dexteritySavingThrowAdvantage;
|
||||
self.dexteritySavingThrowProficiency = monster.dexteritySavingThrowProficiency;
|
||||
self.constitutionSavingThrowAdvantage = monster.constitutionSavingThrowAdvantage;
|
||||
self.constitutionSavingThrowProficiency = monster.constitutionSavingThrowProficiency;
|
||||
self.intelligenceSavingThrowAdvantage = monster.intelligenceSavingThrowAdvantage;
|
||||
self.intelligenceSavingThrowProficiency = monster.intelligenceSavingThrowProficiency;
|
||||
self.wisdomSavingThrowAdvantage = monster.wisdomSavingThrowAdvantage;
|
||||
self.wisdomSavingThrowProficiency = monster.wisdomSavingThrowProficiency;
|
||||
self.charismaSavingThrowAdvantage = monster.charismaSavingThrowAdvantage;
|
||||
self.charismaSavingThrowProficiency = monster.charismaSavingThrowProficiency;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,31 +6,43 @@
|
||||
<attribute name="baseSpeed" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="burrowSpeed" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="canHover" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="charismaSavingThrowAdvantage" attributeType="String" defaultValueString="none"/>
|
||||
<attribute name="charismaSavingThrowProficiency" attributeType="String" defaultValueString="none"/>
|
||||
<attribute name="charismaScore" attributeType="Integer 16" defaultValueString="10" usesScalarValueType="YES"/>
|
||||
<attribute name="climbSpeed" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="constitutionSavingThrowAdvantage" attributeType="String" defaultValueString="none"/>
|
||||
<attribute name="constitutionSavingThrowProficiency" attributeType="String" defaultValueString="none"/>
|
||||
<attribute name="constitutionScore" attributeType="Integer 16" defaultValueString="10" usesScalarValueType="YES"/>
|
||||
<attribute name="customArmor" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="customHP" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="customSpeed" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="dexteritySavingThrowAdvantage" attributeType="String" defaultValueString="none"/>
|
||||
<attribute name="dexteritySavingThrowProficiency" attributeType="String" defaultValueString="none" customClassName="none"/>
|
||||
<attribute name="dexterityScore" attributeType="Integer 16" defaultValueString="10" usesScalarValueType="YES"/>
|
||||
<attribute name="flySpeed" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="hasCustomSpeed" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="hasShield" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="hitDice" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="hpText" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="intelligenceSavingThrowAdvantage" attributeType="String" defaultValueString="none"/>
|
||||
<attribute name="intelligenceSavingThrowProficiency" attributeType="String" defaultValueString="none"/>
|
||||
<attribute name="intelligenceScore" attributeType="Integer 16" defaultValueString="10" usesScalarValueType="YES"/>
|
||||
<attribute name="name" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="natrualArmorBonus" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="otherArmorDescription" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="shieldBonus" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="size" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="strengthSavingThrowAdvantage" attributeType="String" defaultValueString="none"/>
|
||||
<attribute name="strengthSavingThrowProficiency" attributeType="String" defaultValueString="none"/>
|
||||
<attribute name="strengthScore" attributeType="Integer 16" defaultValueString="10" usesScalarValueType="YES"/>
|
||||
<attribute name="subtype" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="swimSpeed" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="type" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="wisdomSavingThrowAdvantage" attributeType="String" defaultValueString="none"/>
|
||||
<attribute name="wisdomSavingThrowProficiency" attributeType="String" defaultValueString="none"/>
|
||||
<attribute name="wisdomScore" attributeType="Integer 16" defaultValueString="10" usesScalarValueType="YES"/>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="Monster" positionX="-63" positionY="-18" width="128" height="463"/>
|
||||
<element name="Monster" positionX="-63" positionY="-18" width="128" height="643"/>
|
||||
</elements>
|
||||
</model>
|
||||
@@ -9,6 +9,7 @@
|
||||
#import "EditMonsterViewController.h"
|
||||
#import "MCBooleanFieldTableViewCell.h"
|
||||
#import "MCIntegerFieldTableViewCell.h"
|
||||
#import "MCRadioFieldTableViewCell.h"
|
||||
#import "MCSelectFieldTableViewCell.h"
|
||||
#import "MCShortStringFieldTableViewCell.h"
|
||||
#import "AppDelegate.h"
|
||||
@@ -23,6 +24,7 @@ const int kSectionIndexBasicInfo = 0;
|
||||
const int kSectionIndexArmor = 1;
|
||||
const int kSectionIndexSpeed = 2;
|
||||
const int kSectionIndexAbilityScores = 3;
|
||||
const int kSectionIndexSavingThrows = 4;
|
||||
|
||||
const int kBasicInfoSectionRowIndexName = 0;
|
||||
const int kBasicInfoSectionRowIndexSize = 1;
|
||||
@@ -54,9 +56,63 @@ const int kAbilityScoreSectionRowIndexIntelligence = 3;
|
||||
const int kAbilityScoreSectionRowIndexWisdom = 4;
|
||||
const int kAbilityScoreSectionRowIndexCharisma = 5;
|
||||
|
||||
const int kSavingThrowsSectionRowIndexStrengthProficiency = 0;
|
||||
const int kSavingThrowsSectionRowIndexStrengthAdvantage = 1;
|
||||
const int kSavingThrowsSectionRowIndexDexterityProficiency = 2;
|
||||
const int kSavingThrowsSectionRowIndexDexterityAdvantage = 3;
|
||||
const int kSavingThrowsSectionRowIndexConstitutionProficiency = 4;
|
||||
const int kSavingThrowsSectionRowIndexConstitutionAdvantage = 5;
|
||||
const int kSavingThrowsSectionRowIndexIntelligenceProficiency = 6;
|
||||
const int kSavingThrowsSectionRowIndexIntelligenceAdvantage = 7;
|
||||
const int kSavingThrowsSectionRowIndexWisdomProficiency = 8;
|
||||
const int kSavingThrowsSectionRowIndexWisdomAdvantage = 9;
|
||||
const int kSavingThrowsSectionRowIndexCharismaProficiency = 10;
|
||||
const int kSavingThrowsSectionRowIndexCharismaAdvantage = 11;
|
||||
|
||||
NSString *const kIdentifierName = @"monster.name";
|
||||
NSString *const kIdentifierSize = @"monster.size";
|
||||
NSString *const kIdentifierType = @"monster.type";
|
||||
NSString *const kIdentifierSubtype = @"monster.subtype";
|
||||
NSString *const kIdentifierAlignment = @"monster.alignment";
|
||||
NSString *const kIdentifierCustomHP = @"monster.customHPText";
|
||||
NSString *const kIdentifierCustomSpeed = @"monster.customSpeed";
|
||||
NSString *const kIdentifierCustomArmor = @"monster.customArmor";
|
||||
NSString *const kIdentifierStrengthScore = @"monster.strengthScore";
|
||||
NSString *const kIdentiferDexterityScore = @"monster.dexterityScore";
|
||||
NSString *const kIdentifierConstitutionScore = @"monster.constitutionScore";
|
||||
NSString *const kIdentifierIntelligenceScore = @"monster.intelligenceScore";
|
||||
NSString *const kIdentifierWisdomScore = @"monster.wisdomScore";
|
||||
NSString *const kIdentifierCharismaScore = @"monster.charismaScore";
|
||||
NSString *const kIdentifierHitDice = @"monster.hitDice";
|
||||
NSString *const kIdentifierBaseSpeed = @"monster.baseSpeed";
|
||||
NSString *const kIdentifierBurrowSpeed = @"monster.burrowSpeed";
|
||||
NSString *const kIdentifierClimbSpeed = @"monster.climbSpeed";
|
||||
NSString *const kIdentifierFlySpeed = @"monster.flySpeed";
|
||||
NSString *const kIdentifierSwimSpeed = @"monster.swimSpeed";
|
||||
NSString *const kIdentifierNaturalArmorBonus = @"monster.naturalArmorBonus";
|
||||
NSString *const kIdentifierHasCustomHP = @"monster.customHP";
|
||||
NSString *const kIdentifierCanHover = @"monster.canHover";
|
||||
NSString *const kIdentifierHasCustomSpeed = @"monster.hasCustomSpeed";
|
||||
NSString *const kIdentifierHasShield = @"monster.hasShield";
|
||||
NSString *const kIdentifierArmorType = @"monster.armorType";
|
||||
NSString *const kIdentifierStrengthSavingThrowAdvantage = @"monster.savingThrows.strength.advantage";
|
||||
NSString *const kIdentifierStrengthSavingThrowProficiency = @"monster.savingThrows.strength.proficiency";
|
||||
NSString *const kIdentifierDexteritySavingThrowAdvantage = @"monster.savingThrows.dexterity.advantage";
|
||||
NSString *const kIdentifierDexteritySavingThrowProficiency = @"monster.savingThrows.dexterity.proficiency";
|
||||
NSString *const kIdentifierConstitutionSavingThrowAdvantage = @"monster.savingThrows.constitution.advantage";
|
||||
NSString *const kIdentifierConstitutionSavingThrowProficiency = @"monster.savingThrows.constitution.proficiency";
|
||||
NSString *const kIdentifierIntelligenceSavingThrowAdvantage = @"monster.savingThrows.intelligence.advantage";
|
||||
NSString *const kIdentifierIntelligenceSavingThrowProficiency = @"monster.savingThrows.intelligence.proficiency";
|
||||
NSString *const kIdentifierWisdomSavingThrowAdvantage = @"monster.savingThrows.wisdom.advantage";
|
||||
NSString *const kIdentifierWisdomSavingThrowProficiency = @"monster.savingThrows.wisdom.proficiency";
|
||||
NSString *const kIdentifierCharismaSavingThrowAdvantage = @"monster.savingThrows.charisma.advantage";
|
||||
NSString *const kIdentifierCharismaSavingThrowProficiency = @"monster.savingThrows.charisma.proficiency";
|
||||
|
||||
@implementation EditMonsterViewController {
|
||||
NSManagedObjectContext *_context;
|
||||
NSArray<MCChoice*>* _armorTypes;
|
||||
NSArray<MCChoice*>* _proficiencyTypes;
|
||||
NSArray<MCChoice*>* _advantageTypes;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
@@ -98,6 +154,22 @@ const int kAbilityScoreSectionRowIndexCharisma = 5;
|
||||
[MCChoice choiceWithLabel:NSLocalizedString(@"Other", @"")
|
||||
andValue:kArmorNameOther],
|
||||
nil];
|
||||
_proficiencyTypes = [NSArray arrayWithObjects:
|
||||
[MCChoice choiceWithLabel:NSLocalizedString(@"None", @"")
|
||||
andValue:kProficiencyTypeNone],
|
||||
[MCChoice choiceWithLabel:NSLocalizedString(@"Proficient", @"")
|
||||
andValue:kProficiencyTypeProficient],
|
||||
[MCChoice choiceWithLabel:NSLocalizedString(@"Expertise", @"")
|
||||
andValue:kProficiencyTypeExpertise],
|
||||
nil];
|
||||
_advantageTypes = [NSArray arrayWithObjects:
|
||||
[MCChoice choiceWithLabel:NSLocalizedString(@"None", @"")
|
||||
andValue:kAdvantageTypeNone],
|
||||
[MCChoice choiceWithLabel:NSLocalizedString(@"Advantage", @"")
|
||||
andValue:kAdvantageTypeAdvantage],
|
||||
[MCChoice choiceWithLabel:NSLocalizedString(@"Disadvantage", @"")
|
||||
andValue:kAdvantageTypeDisadvantage],
|
||||
nil];
|
||||
|
||||
self.monsterTableView.allowsSelection = NO;
|
||||
self.monsterTableView.allowsSelectionDuringEditing = NO;
|
||||
@@ -188,6 +260,24 @@ const int kAbilityScoreSectionRowIndexCharisma = 5;
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (MCRadioFieldTableViewCell*) makeRadioCellFromTableView:(UITableView*)tableView
|
||||
withIdentifier:(NSString*)identifier
|
||||
label:(NSString*)label
|
||||
initialValue:(NSObject*)initialValue
|
||||
andChoices:(NSArray*)choices {
|
||||
MCRadioFieldTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MCRadioField"];
|
||||
if (!cell || ![cell isKindOfClass:[MCRadioFieldTableViewCell class]]) {
|
||||
return nil;
|
||||
}
|
||||
cell.delegate = self;
|
||||
cell.identifier = identifier;
|
||||
cell.label = label;
|
||||
// TODO: possibly swap these two
|
||||
cell.selectedValue = initialValue;
|
||||
cell.choices = choices;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
#pragma mark - Navigation
|
||||
|
||||
@@ -222,6 +312,8 @@ const int kAbilityScoreSectionRowIndexCharisma = 5;
|
||||
return 8;
|
||||
case kSectionIndexAbilityScores:
|
||||
return 6;
|
||||
case kSectionIndexSavingThrows:
|
||||
return 12; // 12
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -229,7 +321,7 @@ const int kAbilityScoreSectionRowIndexCharisma = 5;
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return 3;
|
||||
return 5;
|
||||
}
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView
|
||||
@@ -243,6 +335,8 @@ titleForHeaderInSection:(NSInteger)section {
|
||||
return NSLocalizedString(@"Speed", @"Section title");
|
||||
case kSectionIndexAbilityScores:
|
||||
return NSLocalizedString(@"Ability Scores", @"Section title");
|
||||
case kSectionIndexSavingThrows:
|
||||
return NSLocalizedString(@"Saving Throws", @"Section title");
|
||||
default:
|
||||
return nil;
|
||||
}
|
||||
@@ -257,49 +351,49 @@ titleForHeaderInSection:(NSInteger)section {
|
||||
switch (indexPath.row) {
|
||||
case kBasicInfoSectionRowIndexName:
|
||||
newCell = [self makeShortStringCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.name"
|
||||
withIdentifier:kIdentifierName
|
||||
label:NSLocalizedString(@"Name", @"Placeholder text for the name of a monster or NPC.")
|
||||
andInitialValue:self.editingMonster.name];
|
||||
break;
|
||||
case kBasicInfoSectionRowIndexSize:
|
||||
newCell = [self makeShortStringCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.size"
|
||||
withIdentifier:kIdentifierSize
|
||||
label:NSLocalizedString(@"Size", @"Placehodler text for the size of a monster or NPC.")
|
||||
andInitialValue:self.editingMonster.size];
|
||||
break;
|
||||
case kBasicInfoSectionRowIndexType:
|
||||
newCell = [self makeShortStringCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.type"
|
||||
withIdentifier:kIdentifierType
|
||||
label:NSLocalizedString(@"Type", @"Placehodler text for the type of a monster or NPC.")
|
||||
andInitialValue:self.editingMonster.type];
|
||||
break;
|
||||
case kBasicInfoSectionRowIndexSubtype:
|
||||
newCell = [self makeShortStringCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.subtype"
|
||||
withIdentifier:kIdentifierSubtype
|
||||
label:NSLocalizedString(@"Subtype", @"Placeholder text for the subtype of a monster or NPC.")
|
||||
andInitialValue:self.editingMonster.subtype];
|
||||
break;
|
||||
case kBasicInfoSectionRowIndexAlignment:
|
||||
newCell = [self makeShortStringCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.alignment"
|
||||
withIdentifier:kIdentifierAlignment
|
||||
label: NSLocalizedString(@"Alignment", @"Placeholder text for the alignment of a monster or NPC.")
|
||||
andInitialValue:self.editingMonster.alignment];
|
||||
break;
|
||||
case kBasicInfoSectionRowIndexHitDice:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.hitDice"
|
||||
withIdentifier:kIdentifierHitDice
|
||||
label:NSLocalizedString(@"Hit Dice", @"")
|
||||
andInitialValue:self.editingMonster.hitDice];
|
||||
break;
|
||||
case kBasicInfoSectionRowIndexCustomHP:
|
||||
newCell = [self makeBooleanCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.customHP"
|
||||
withIdentifier:kIdentifierHasCustomHP
|
||||
label:NSLocalizedString(@"Custom HP", @"")
|
||||
andInitialValue:self.editingMonster.customHP];
|
||||
break;
|
||||
case kBasicInfoSectionRowIndexCustomHPText:
|
||||
newCell = [self makeShortStringCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.customHPText"
|
||||
withIdentifier:kIdentifierCustomHP
|
||||
label:NSLocalizedString(@"Custom HP Text", @"")
|
||||
andInitialValue:self.editingMonster.hpText];
|
||||
break;
|
||||
@@ -309,26 +403,26 @@ titleForHeaderInSection:(NSInteger)section {
|
||||
switch (indexPath.row) {
|
||||
case kArmorSectionRowIndexArmorType:
|
||||
newCell = [self makeSelectCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.armorType"
|
||||
withIdentifier:kIdentifierArmorType
|
||||
label:NSLocalizedString(@"Type", @"")
|
||||
initialValue:self.editingMonster.armorType
|
||||
andChoices:_armorTypes];
|
||||
break;
|
||||
case kArmorSectionRowIndexHasShield:
|
||||
newCell = [self makeBooleanCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.hasShield"
|
||||
withIdentifier:kIdentifierHasShield
|
||||
label:NSLocalizedString(@"Shield", @"")
|
||||
andInitialValue:self.editingMonster.hasShield];
|
||||
break;
|
||||
case kArmorSectionRowIndexCustomArmor:
|
||||
newCell = [self makeShortStringCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.customArmor"
|
||||
withIdentifier:kIdentifierCustomArmor
|
||||
label:NSLocalizedString(@"Custom Armor", @"")
|
||||
andInitialValue:self.editingMonster.customArmor];
|
||||
break;
|
||||
case kArmorSectionRowIndexNaturalArmorBonus:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.naturalArmorBonus"
|
||||
withIdentifier:kIdentifierNaturalArmorBonus
|
||||
label:NSLocalizedString(@"Natural Armor Bonus", @"")
|
||||
andInitialValue:self.editingMonster.naturalArmorBonus];
|
||||
break;
|
||||
@@ -338,49 +432,49 @@ titleForHeaderInSection:(NSInteger)section {
|
||||
switch (indexPath.row) {
|
||||
case kSpeedSectionRowIndexBaseSpeed:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.baseSpeed"
|
||||
withIdentifier:kIdentifierBaseSpeed
|
||||
label:NSLocalizedString(@"Base", @"")
|
||||
andInitialValue:self.editingMonster.baseSpeed];
|
||||
break;
|
||||
case kSpeedSectionRowIndexBurrowSpeed:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.burrowSpeed"
|
||||
withIdentifier:kIdentifierBurrowSpeed
|
||||
label:NSLocalizedString(@"Burrow", @"")
|
||||
andInitialValue:self.editingMonster.burrowSpeed];
|
||||
break;
|
||||
case kSpeedSectionRowIndexClimbSpeed:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.climbSpeed"
|
||||
withIdentifier:kIdentifierClimbSpeed
|
||||
label:NSLocalizedString(@"Climb", @"")
|
||||
andInitialValue:self.editingMonster.climbSpeed];
|
||||
break;
|
||||
case kSpeedSectionRowIndexFlySpeed:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.flySpeed"
|
||||
withIdentifier:kIdentifierFlySpeed
|
||||
label:NSLocalizedString(@"Fly", @"")
|
||||
andInitialValue:self.editingMonster.flySpeed];
|
||||
break;
|
||||
case kSpeedSectionRowIndexCanHover:
|
||||
newCell = [self makeBooleanCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.canHover"
|
||||
withIdentifier:kIdentifierCanHover
|
||||
label:NSLocalizedString(@"Hover", @"")
|
||||
andInitialValue:self.editingMonster.canHover];
|
||||
break;
|
||||
case kSpeedSectionRowIndexSwimSpeed:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.swimSpeed"
|
||||
withIdentifier:kIdentifierSwimSpeed
|
||||
label:NSLocalizedString(@"Swim", @"")
|
||||
andInitialValue:self.editingMonster.swimSpeed];
|
||||
break;
|
||||
case kSpeedSectionRowIndexHasCustomSpeed:
|
||||
newCell = [self makeBooleanCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.hasCustomSpeed"
|
||||
withIdentifier:kIdentifierHasCustomSpeed
|
||||
label:NSLocalizedString(@"Custom Speed", @"")
|
||||
andInitialValue:self.editingMonster.hasCustomSpeed];
|
||||
break;
|
||||
case kSpeedSectionRowIndexCustomSpeed:
|
||||
newCell = [self makeShortStringCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.customSpeed"
|
||||
withIdentifier:kIdentifierCustomSpeed
|
||||
label:NSLocalizedString(@"Custom Speed", @"")
|
||||
andInitialValue:self.editingMonster.customSpeed];
|
||||
break;
|
||||
@@ -390,43 +484,131 @@ titleForHeaderInSection:(NSInteger)section {
|
||||
switch (indexPath.row) {
|
||||
case kAbilityScoreSectionRowIndexStrength:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.strengthScore"
|
||||
withIdentifier:kIdentifierStrengthScore
|
||||
label:NSLocalizedString(@"STR", @"Placeholder abbreviation for the strength score of a monster or NPC.")
|
||||
andInitialValue:self.editingMonster.strengthScore];
|
||||
break;
|
||||
case kAbilityScoreSectionRowIndexDexterity:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.dexterityScore"
|
||||
withIdentifier:kIdentiferDexterityScore
|
||||
label:NSLocalizedString(@"DEX", @"Placeholder abbreviation for the dexterity score of a monster or NPC.")
|
||||
andInitialValue:self.editingMonster.dexterityScore];
|
||||
break;
|
||||
case kAbilityScoreSectionRowIndexConstitution:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.constitutionScore"
|
||||
withIdentifier:kIdentifierConstitutionScore
|
||||
label:NSLocalizedString(@"CON", @"Placeholder abbreviation for the constitution score of a monster or NPC.")
|
||||
andInitialValue:self.editingMonster.constitutionScore];
|
||||
break;
|
||||
case kAbilityScoreSectionRowIndexIntelligence:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.intelligenceScore"
|
||||
withIdentifier:kIdentifierIntelligenceScore
|
||||
label:NSLocalizedString(@"INT", @"Placeholder abbreviation for the intelligence score of a monster or NPC.")
|
||||
andInitialValue:self.editingMonster.intelligenceScore];
|
||||
break;
|
||||
case kAbilityScoreSectionRowIndexWisdom:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.wisdomScore"
|
||||
withIdentifier:kIdentifierWisdomScore
|
||||
label:NSLocalizedString(@"WIS", @"Placeholder abbreviation for the wisdom score of a monster or NPC.")
|
||||
andInitialValue:self.editingMonster.wisdomScore];
|
||||
break;
|
||||
case kAbilityScoreSectionRowIndexCharisma:
|
||||
newCell = [self makeIntegerCellFromTableView:self.monsterTableView
|
||||
withIdentifier:@"monster.charismaScore"
|
||||
withIdentifier:kIdentifierCharismaScore
|
||||
label:NSLocalizedString(@"CHA", @"Placeholder abbreviation for the charisma score of a monster or NPC.")
|
||||
andInitialValue:self.editingMonster.charismaScore];
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
case kSectionIndexSavingThrows:
|
||||
switch (indexPath.row) {
|
||||
case kSavingThrowsSectionRowIndexStrengthProficiency:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierStrengthSavingThrowProficiency
|
||||
label:NSLocalizedString(@"Strength Proficiency", @"")
|
||||
initialValue:self.editingMonster.strengthSavingThrowProficiency
|
||||
andChoices:_proficiencyTypes];
|
||||
break;
|
||||
case kSavingThrowsSectionRowIndexStrengthAdvantage:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierStrengthSavingThrowAdvantage
|
||||
label:NSLocalizedString(@"Strength Advantage", @"")
|
||||
initialValue:self.editingMonster.strengthSavingThrowAdvantage
|
||||
andChoices:_advantageTypes];
|
||||
break;
|
||||
case kSavingThrowsSectionRowIndexDexterityProficiency:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierDexteritySavingThrowProficiency
|
||||
label:NSLocalizedString(@"Dexterity Proficiency", @"")
|
||||
initialValue:self.editingMonster.dexteritySavingThrowProficiency
|
||||
andChoices:_proficiencyTypes];
|
||||
break;
|
||||
case kSavingThrowsSectionRowIndexDexterityAdvantage:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierDexteritySavingThrowAdvantage
|
||||
label:NSLocalizedString(@"Dexterity Advantage", @"")
|
||||
initialValue:self.editingMonster.dexteritySavingThrowAdvantage
|
||||
andChoices:_advantageTypes];
|
||||
break;
|
||||
case kSavingThrowsSectionRowIndexConstitutionProficiency:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierConstitutionSavingThrowProficiency
|
||||
label:NSLocalizedString(@"Constitution Proficiency", @"")
|
||||
initialValue:self.editingMonster.constitutionSavingThrowProficiency
|
||||
andChoices:_proficiencyTypes];
|
||||
break;
|
||||
case kSavingThrowsSectionRowIndexConstitutionAdvantage:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierConstitutionSavingThrowAdvantage
|
||||
label:NSLocalizedString(@"Constitution Advantage", @"")
|
||||
initialValue:self.editingMonster.constitutionSavingThrowAdvantage
|
||||
andChoices:_advantageTypes];
|
||||
break;
|
||||
case kSavingThrowsSectionRowIndexIntelligenceProficiency:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierIntelligenceSavingThrowProficiency
|
||||
label:NSLocalizedString(@"Intelligence Proficiency", @"")
|
||||
initialValue:self.editingMonster.intelligenceSavingThrowProficiency
|
||||
andChoices:_proficiencyTypes];
|
||||
break;
|
||||
case kSavingThrowsSectionRowIndexIntelligenceAdvantage:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierIntelligenceSavingThrowAdvantage
|
||||
label:NSLocalizedString(@"Intelligence Advantage", @"")
|
||||
initialValue:self.editingMonster.intelligenceSavingThrowAdvantage
|
||||
andChoices:_advantageTypes];
|
||||
break;
|
||||
case kSavingThrowsSectionRowIndexWisdomProficiency:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierWisdomSavingThrowProficiency
|
||||
label:NSLocalizedString(@"Wisdom Proficiency", @"")
|
||||
initialValue:self.editingMonster.wisdomSavingThrowProficiency
|
||||
andChoices:_proficiencyTypes];
|
||||
break;
|
||||
case kSavingThrowsSectionRowIndexWisdomAdvantage:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierWisdomSavingThrowAdvantage
|
||||
label:NSLocalizedString(@"Wisdom Advantage", @"")
|
||||
initialValue:self.editingMonster.wisdomSavingThrowAdvantage
|
||||
andChoices:_advantageTypes];
|
||||
break;
|
||||
case kSavingThrowsSectionRowIndexCharismaProficiency:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierCharismaSavingThrowProficiency
|
||||
label:NSLocalizedString(@"Charisma Proficiency", @"")
|
||||
initialValue:self.editingMonster.charismaSavingThrowProficiency
|
||||
andChoices:_proficiencyTypes];
|
||||
break;
|
||||
case kSavingThrowsSectionRowIndexCharismaAdvantage:
|
||||
newCell = [self makeRadioCellFromTableView:self.monsterTableView
|
||||
withIdentifier:kIdentifierCharismaSavingThrowAdvantage
|
||||
label:NSLocalizedString(@"Charisma Advantage", @"")
|
||||
initialValue:self.editingMonster.charismaSavingThrowAdvantage
|
||||
andChoices:_advantageTypes];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!newCell) {
|
||||
@@ -441,69 +623,97 @@ titleForHeaderInSection:(NSInteger)section {
|
||||
|
||||
- (void)editableValueDidChange:(NSObject*)value forIdentifier:(NSString*)identifier andType:(NSString*)type {
|
||||
if ([kMCFieldValueTypeString isEqualToString:type]) {
|
||||
if ([@"monster.name" isEqualToString:identifier]) {
|
||||
if ([kIdentifierName isEqualToString:identifier]) {
|
||||
self.editingMonster.name = (NSString*)value;
|
||||
} else if ([@"monster.size" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierSize isEqualToString:identifier]) {
|
||||
self.editingMonster.size = (NSString*)value;
|
||||
} else if ([@"monster.type" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierType isEqualToString:identifier]) {
|
||||
self.editingMonster.type = (NSString*)value;
|
||||
} else if ([@"monster.subtype" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierSubtype isEqualToString:identifier]) {
|
||||
self.editingMonster.subtype = (NSString*)value;
|
||||
} else if ([@"monster.alignment" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierAlignment isEqualToString:identifier]) {
|
||||
self.editingMonster.alignment = (NSString*)value;
|
||||
} else if ([@"monster.customHPText" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierCustomHP isEqualToString:identifier]) {
|
||||
self.editingMonster.hpText = (NSString*)value;
|
||||
} else if ([@"monster.customSpeed" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierCustomSpeed isEqualToString:identifier]) {
|
||||
self.editingMonster.customSpeed = (NSString*)value;
|
||||
} else if ([@"monster.customArmor" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierCustomArmor isEqualToString:identifier]) {
|
||||
self.editingMonster.customArmor = (NSString*)value;
|
||||
}
|
||||
}
|
||||
if ([kMCFieldValueTypeInteger isEqualToString:type]) {
|
||||
if ([@"monster.strengthScore" isEqualToString:identifier]) {
|
||||
if ([kIdentifierStrengthScore isEqualToString:identifier]) {
|
||||
self.editingMonster.strengthScore = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.dexterityScore" isEqualToString:identifier]) {
|
||||
} else if ([kIdentiferDexterityScore isEqualToString:identifier]) {
|
||||
self.editingMonster.dexterityScore = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.constitutionScore" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierConstitutionScore isEqualToString:identifier]) {
|
||||
self.editingMonster.constitutionScore = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.intelligenceScore" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierIntelligenceScore isEqualToString:identifier]) {
|
||||
self.editingMonster.intelligenceScore = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.wisdomScore" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierWisdomScore isEqualToString:identifier]) {
|
||||
self.editingMonster.wisdomScore = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.charismaScore" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierCharismaScore isEqualToString:identifier]) {
|
||||
self.editingMonster.charismaScore = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.hitDice" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierHitDice isEqualToString:identifier]) {
|
||||
self.editingMonster.hitDice = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.baseSpeed" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierBaseSpeed isEqualToString:identifier]) {
|
||||
self.editingMonster.baseSpeed = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.burrowSpeed" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierBurrowSpeed isEqualToString:identifier]) {
|
||||
self.editingMonster.burrowSpeed = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.climbSpeed" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierClimbSpeed isEqualToString:identifier]) {
|
||||
self.editingMonster.climbSpeed = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.flySpeed" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierFlySpeed isEqualToString:identifier]) {
|
||||
self.editingMonster.flySpeed = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.swimSpeed" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierSwimSpeed isEqualToString:identifier]) {
|
||||
self.editingMonster.swimSpeed = [(NSNumber*)value intValue];
|
||||
} else if ([@"monster.naturalArmorBonus" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierNaturalArmorBonus isEqualToString:identifier]) {
|
||||
self.editingMonster.naturalArmorBonus = [(NSNumber*)value intValue];
|
||||
}
|
||||
}
|
||||
if ([kMCFieldValueTypeBoolean isEqualToString:type]) {
|
||||
if ([@"monster.customHP" isEqualToString:identifier]) {
|
||||
if ([kIdentifierHasCustomHP isEqualToString:identifier]) {
|
||||
self.editingMonster.customHP = [(NSNumber*)value boolValue];
|
||||
} else if ([@"monster.canHover" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierCanHover isEqualToString:identifier]) {
|
||||
self.editingMonster.canHover = [(NSNumber*)value boolValue];
|
||||
} else if ([@"monster.hasCustomSpeed" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierHasCustomSpeed isEqualToString:identifier]) {
|
||||
self.editingMonster.hasCustomSpeed = [(NSNumber*)value boolValue];
|
||||
} else if ([@"monster.hasShield" isEqualToString:identifier]) {
|
||||
} else if ([kIdentifierHasShield isEqualToString:identifier]) {
|
||||
self.editingMonster.hasShield = [(NSNumber*)value boolValue];
|
||||
}
|
||||
}
|
||||
if ([kMCFieldValueTypeChoice isEqualToString:type]) {
|
||||
if ([@"monster.armorType" isEqualToString:identifier]) {
|
||||
if ([kIdentifierArmorType isEqualToString:identifier]) {
|
||||
self.editingMonster.armorType = (NSString*)value;
|
||||
} else if ([kIdentifierStrengthSavingThrowAdvantage isEqualToString:identifier]) {
|
||||
self.editingMonster.strengthSavingThrowAdvantage = (NSString*)value;
|
||||
} else if ([kIdentifierStrengthSavingThrowProficiency isEqualToString:identifier]) {
|
||||
self.editingMonster.strengthSavingThrowProficiency = (NSString*)value;
|
||||
} else if ([kIdentifierDexteritySavingThrowAdvantage isEqualToString:identifier]) {
|
||||
self.editingMonster.dexteritySavingThrowAdvantage = (NSString*)value;
|
||||
} else if ([kIdentifierDexteritySavingThrowProficiency isEqualToString:identifier]) {
|
||||
self.editingMonster.dexteritySavingThrowProficiency = (NSString*)value;
|
||||
} else if ([kIdentifierConstitutionSavingThrowAdvantage isEqualToString:identifier]) {
|
||||
self.editingMonster.constitutionSavingThrowAdvantage = (NSString*)value;
|
||||
} else if ([kIdentifierConstitutionSavingThrowProficiency isEqualToString:identifier]) {
|
||||
self.editingMonster.constitutionSavingThrowProficiency = (NSString*)value;
|
||||
} else if ([kIdentifierIntelligenceSavingThrowAdvantage isEqualToString:identifier]) {
|
||||
self.editingMonster.intelligenceSavingThrowAdvantage = (NSString*)value;
|
||||
} else if ([kIdentifierIntelligenceSavingThrowProficiency isEqualToString:identifier]) {
|
||||
self.editingMonster.intelligenceSavingThrowProficiency = (NSString*)value;
|
||||
} else if ([kIdentifierWisdomSavingThrowAdvantage isEqualToString:identifier]) {
|
||||
self.editingMonster.wisdomSavingThrowAdvantage = (NSString*)value;
|
||||
} else if ([kIdentifierWisdomSavingThrowProficiency isEqualToString:identifier]) {
|
||||
self.editingMonster.wisdomSavingThrowProficiency = (NSString*)value;
|
||||
} else if ([kIdentifierCharismaSavingThrowAdvantage isEqualToString:identifier]) {
|
||||
self.editingMonster.charismaSavingThrowAdvantage = (NSString*)value;
|
||||
} else if ([kIdentifierCharismaSavingThrowProficiency isEqualToString:identifier]) {
|
||||
self.editingMonster.charismaSavingThrowProficiency = (NSString*)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
return UITableViewAutomaticDimension;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// MCRadioFieldTableViewCell.h
|
||||
// MonsterCards
|
||||
//
|
||||
// Created by Tom Hicks on 9/26/20.
|
||||
// Copyright © 2020 Tom Hicks. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "MCFormFieldDelegate.h"
|
||||
#import "MCChoice.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MCRadioFieldTableViewCell : UITableViewCell
|
||||
|
||||
@property NSString* identifier;
|
||||
@property NSString* label;
|
||||
@property NSObject* selectedValue;
|
||||
@property NSArray<MCChoice*>* choices;
|
||||
|
||||
@property (weak, nonatomic) id<MCFormFieldDelegate> delegate;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *labelView;
|
||||
@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentedControl;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
131
iOS/MonsterCards/Views/FormFields/MCRadioFieldTableViewCell.m
Normal file
131
iOS/MonsterCards/Views/FormFields/MCRadioFieldTableViewCell.m
Normal file
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// MCRadioFieldTableViewCell.m
|
||||
// MonsterCards
|
||||
//
|
||||
// Created by Tom Hicks on 9/26/20.
|
||||
// Copyright © 2020 Tom Hicks. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MCRadioFieldTableViewCell.h"
|
||||
|
||||
@implementation MCRadioFieldTableViewCell {
|
||||
MCChoice* _selectedChoice;
|
||||
}
|
||||
|
||||
-(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<MCChoice*> *matchingChoices = [array filteredArrayUsingPredicate:predicate];
|
||||
MCChoice *foundChoice = matchingChoices.count > 0 ? matchingChoices.firstObject : nil;
|
||||
return foundChoice;
|
||||
}
|
||||
|
||||
-(void)notifyChangedValue {
|
||||
NSUInteger selectedIndex = [_choices indexOfObject:_selectedChoice];
|
||||
[self.segmentedControl setSelectedSegmentIndex:selectedIndex];
|
||||
|
||||
if (_delegate) {
|
||||
[_delegate editableValueDidChange:_selectedValue
|
||||
forIdentifier:_identifier
|
||||
andType:kMCFieldValueTypeChoice];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)updateSegments {
|
||||
if (_segmentedControl) {
|
||||
[_segmentedControl removeAllSegments];
|
||||
int index = 0;
|
||||
for (MCChoice *choice in _choices) {
|
||||
[_segmentedControl insertSegmentWithTitle:choice.label atIndex:index animated:NO];
|
||||
index++;
|
||||
}
|
||||
_segmentedControl.selectedSegmentIndex = [_choices indexOfObject:_selectedChoice];
|
||||
}
|
||||
}
|
||||
|
||||
@synthesize choices = _choices;
|
||||
-(void)setChoices:(NSArray<MCChoice*>*)choices {
|
||||
MCChoice *foundChoice = [self findChoiceWithValue:_selectedValue
|
||||
inArray:choices];
|
||||
if ([_choices isEqualToArray:choices]) {
|
||||
// Choices are equivalent so selected value. Pointer may have changed but content hasn't.
|
||||
_selectedChoice = foundChoice;
|
||||
} else if (foundChoice) {
|
||||
// Choices are different but selected value is in the new choices. Pointer may have changed but content hasn't.
|
||||
_selectedChoice = foundChoice;
|
||||
} else {
|
||||
// Choices are different and selected value is not in the new choices. Select the first choice or nil if there are none.
|
||||
_selectedChoice = [choices firstObject];
|
||||
}
|
||||
_choices = choices;
|
||||
|
||||
if (_selectedValue != foundChoice.value) {
|
||||
self.selectedValue = foundChoice.value;
|
||||
}
|
||||
|
||||
[self updateSegments];
|
||||
}
|
||||
-(NSArray<MCChoice*>*)choices {
|
||||
return _choices;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@synthesize selectedValue = _selectedValue;
|
||||
-(void)setSelectedValue:(NSObject*)value {
|
||||
NSObject *newValue = nil;
|
||||
MCChoice *foundChoice = [self findChoiceWithValue:value inArray:_choices];
|
||||
if (!_choices) {
|
||||
newValue = value;
|
||||
} else if (!foundChoice) {
|
||||
newValue = nil;
|
||||
} else {
|
||||
newValue = foundChoice.value;
|
||||
}
|
||||
_selectedChoice = foundChoice;
|
||||
if (_selectedValue != newValue) {
|
||||
_selectedValue = newValue;
|
||||
[self notifyChangedValue];
|
||||
}
|
||||
}
|
||||
-(NSObject*)selectedValue {
|
||||
return _selectedValue;
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[super awakeFromNib];
|
||||
// Initialization code
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
|
||||
[super setSelected:selected animated:animated];
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
- (IBAction)selectedSegmentChanged:(id)sender {
|
||||
NSInteger selectedIndex = _segmentedControl.selectedSegmentIndex;
|
||||
MCChoice *newChoice = [_choices objectAtIndex:selectedIndex];
|
||||
_selectedChoice = newChoice;
|
||||
_selectedValue = _selectedChoice.value;
|
||||
[self notifyChangedValue];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property (weak, nonatomic) id<MCFormFieldDelegate> delegate;
|
||||
@property (weak, nonatomic) IBOutlet UITextField *textField;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *labelView;
|
||||
@property (nonatomic) UIPickerView *pickerView;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -12,32 +12,63 @@
|
||||
MCChoice* _selectedChoice;
|
||||
}
|
||||
|
||||
-(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<MCChoice*> *matchingChoices = [array filteredArrayUsingPredicate:predicate];
|
||||
MCChoice *foundChoice = matchingChoices.count > 0 ? matchingChoices.firstObject : nil;
|
||||
return foundChoice;
|
||||
}
|
||||
|
||||
-(void)notifyChangedValue {
|
||||
[self updateView];
|
||||
|
||||
if (_delegate) {
|
||||
[_delegate editableValueDidChange:_selectedValue
|
||||
forIdentifier:_identifier
|
||||
andType:kMCFieldValueTypeChoice];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)updateView {
|
||||
self.textField.text = _selectedChoice.label;
|
||||
NSInteger selectedRow = [_choices indexOfObject:_selectedChoice];
|
||||
[self.pickerView selectRow:selectedRow inComponent:0 animated:YES];
|
||||
|
||||
}
|
||||
|
||||
@synthesize choices = _choices;
|
||||
-(void)setChoices:(NSArray<MCChoice*>*)choices {
|
||||
// TODO: only do this if choices is different
|
||||
// TODO: update selectedValue and selectedIndex
|
||||
MCChoice *foundChoice = [self findChoiceWithValue:_selectedValue
|
||||
inArray:choices];
|
||||
if ([_choices isEqualToArray:choices]) {
|
||||
// Choices are equivalent so selected value. Pointer may have changed but content hasn't.
|
||||
_selectedChoice = foundChoice;
|
||||
} else if (foundChoice) {
|
||||
// Choices are different but selected value is in the new choices. Pointer may have changed but content hasn't.
|
||||
_selectedChoice = foundChoice;
|
||||
} else {
|
||||
// Choices are different and selected value is not in the new choices. Select the first choice or nil if there are none.
|
||||
_selectedChoice = [choices firstObject];
|
||||
}
|
||||
_choices = choices;
|
||||
|
||||
if (![_choices isEqualToArray:choices]) {
|
||||
self.selectedValue = _selectedValue;
|
||||
} else if (choices) {
|
||||
self.selectedValue = [choices firstObject].value;
|
||||
if (_selectedValue != foundChoice.value) {
|
||||
self.selectedValue = foundChoice.value;
|
||||
}
|
||||
|
||||
[self updateView];
|
||||
}
|
||||
-(NSArray<MCChoice*>*)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]) {
|
||||
@@ -51,42 +82,23 @@
|
||||
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<MCChoice*> *matchingChoices = [_choices filteredArrayUsingPredicate:predicate];
|
||||
MCChoice *foundChoice = matchingChoices.count > 0 ? matchingChoices.firstObject : nil;
|
||||
return foundChoice;
|
||||
}
|
||||
|
||||
@synthesize selectedValue = _selectedValue;
|
||||
-(void)setSelectedValue:(NSObject*)value {
|
||||
NSObject *newValue = nil;
|
||||
MCChoice *foundChoice = [self findChoiceWithValue:value inArray:_choices];
|
||||
if (!_choices) {
|
||||
// choices hasn't been initialized yet so just set our selected value until choices is set
|
||||
_selectedValue = value;
|
||||
newValue = value;
|
||||
} else if (!foundChoice) {
|
||||
newValue = nil;
|
||||
} else {
|
||||
newValue = foundChoice.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];
|
||||
if (_selectedValue != newValue) {
|
||||
_selectedValue = newValue;
|
||||
[self notifyChangedValue];
|
||||
}
|
||||
}
|
||||
self.textField.text = _selectedChoice != nil
|
||||
? _selectedChoice.label != nil
|
||||
? _selectedChoice.label
|
||||
: @""
|
||||
: @"";
|
||||
}
|
||||
-(NSObject*)selectedValue {
|
||||
return _selectedValue;
|
||||
@@ -94,10 +106,11 @@
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[super awakeFromNib];
|
||||
UIPickerView *childPicker = [[UIPickerView alloc] init];
|
||||
childPicker.delegate = self;
|
||||
childPicker.dataSource = self;
|
||||
self.textField.inputView = childPicker;
|
||||
self.pickerView = [[UIPickerView alloc] init];
|
||||
self.pickerView.delegate = self;
|
||||
self.pickerView.dataSource = self;
|
||||
self.textField.inputView = self.pickerView;
|
||||
self.pickerView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
UIToolbar *toolbar = [[UIToolbar alloc] init];
|
||||
[toolbar sizeToFit];
|
||||
@@ -154,4 +167,10 @@ numberOfRowsInComponent:(NSInteger)component {
|
||||
self.selectedValue = _selectedChoice.value;
|
||||
}
|
||||
|
||||
#pragma mark - UITextFieldDelegate
|
||||
|
||||
- (void)textFieldDidBeginEditing:(UITextField *)textField {
|
||||
[self updateView];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user