[ios] Added validation for editior's fields.

This commit is contained in:
VladiMihaylenko 2016-04-06 17:03:56 +03:00 committed by Alex Zolotarev
parent 225b60b872
commit 9fb9f1dbd7
5 changed files with 132 additions and 12 deletions

View file

@ -1,9 +1,12 @@
@class MWMEditorTextTableViewCell;
@protocol MWMEditorCellProtocol <NSObject>
@required
- (void)cell:(UITableViewCell *)cell changedText:(NSString *)changeText;
- (void)cell:(MWMEditorTextTableViewCell *)cell changedText:(NSString *)changeText;
- (void)cell:(UITableViewCell *)cell changeSwitch:(BOOL)changeSwitch;
- (void)cellSelect:(UITableViewCell *)cell;
- (void)tryToChangeInvalidStateForCell:(MWMEditorTextTableViewCell *)cell;
@optional
- (void)fieldIsCorrect:(BOOL)isCorrect;

View file

@ -10,4 +10,14 @@
placeholder:(NSString *)placeholder
keyboardType:(UIKeyboardType)keyboardType;
- (void)configWithDelegate:(id<MWMEditorCellProtocol>)delegate
icon:(UIImage *)icon
text:(NSString *)text
placeholder:(NSString *)placeholder
errorMessage:(NSString *)errorMessage
isValid:(BOOL)isValid
keyboardType:(UIKeyboardType)keyboardType;
@property (weak, nonatomic, readonly) IBOutlet UITextField * textField;
@end

View file

@ -7,10 +7,16 @@
@interface MWMEditorTextTableViewCell () <UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UIImageView * icon;
@property (weak, nonatomic) IBOutlet UITextField * textField;
@property (weak, nonatomic, readwrite) IBOutlet UITextField * textField;
@property (weak, nonatomic) IBOutlet UILabel * errorLabel;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * errorLabelTopSpace;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * labelHeight;
@property (weak, nonatomic) id<MWMEditorCellProtocol> delegate;
@property (nonatomic) BOOL isValid;
@end
@implementation MWMEditorTextTableViewCell
@ -20,19 +26,64 @@
text:(NSString *)text
placeholder:(NSString *)placeholder
keyboardType:(UIKeyboardType)keyboardType
{
[self configWithDelegate:delegate icon:icon text:text placeholder:placeholder
errorMessage:nil isValid:YES keyboardType:keyboardType];
}
- (void)configWithDelegate:(id<MWMEditorCellProtocol>)delegate
icon:(UIImage *)icon
text:(NSString *)text
placeholder:(NSString *)placeholder
errorMessage:(NSString *)errorMessage
isValid:(BOOL)isValid
keyboardType:(UIKeyboardType)keyboardType
{
self.delegate = delegate;
self.icon.image = icon;
self.icon.mwm_coloring = MWMImageColoringBlack;
self.icon.hidden = (icon == nil);
self.textField.text = text;
self.textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholder attributes:
@{NSForegroundColorAttributeName : [UIColor blackHintText]}];
self.errorLabel.text = errorMessage;
self.textField.keyboardType = keyboardType;
self.textField.backgroundColor = [UIColor clearColor];
self.isValid = isValid;
[self processValidation];
}
- (void)processValidation
{
if (self.isValid)
{
self.labelHeight.priority = UILayoutPriorityDefaultHigh;
self.errorLabelTopSpace.constant = 0;
self.contentView.backgroundColor = [UIColor white];
}
else
{
self.labelHeight.priority = UILayoutPriorityDefaultLow;
self.errorLabelTopSpace.constant = 4;
self.contentView.backgroundColor = [UIColor errorPink];
}
[self layoutIfNeeded];
}
#pragma mark - UITextFieldDelegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (!self.isValid)
{
self.isValid = YES;
[self processValidation];
[self.delegate tryToChangeInvalidStateForCell:self];
}
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self.delegate cell:self changedText:textField.text];

View file

@ -3,15 +3,16 @@
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="KGk-i7-Jjw" customClass="MWMEditorTextTableViewCell">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="56" id="KGk-i7-Jjw" customClass="MWMEditorTextTableViewCell">
<rect key="frame" x="0.0" y="0.0" width="320" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
<rect key="frame" x="0.0" y="0.0" width="320" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="320" height="58.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="5uK-5Q-cg0">
@ -24,10 +25,11 @@
<userDefinedRuntimeAttribute type="string" keyPath="coloring" value="MWMBlack"/>
</userDefinedRuntimeAttributes>
</imageView>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="krN-k2-9qO">
<rect key="frame" x="60" y="0.0" width="252" height="44"/>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="krN-k2-9qO">
<rect key="frame" x="60" y="12" width="252" height="20"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" priority="750" constant="44" id="RYF-oc-ZOx"/>
<constraint firstAttribute="height" constant="20" id="P3n-mD-g5V"/>
</constraints>
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="17"/>
<textInputTraits key="textInputTraits"/>
@ -40,12 +42,29 @@
<outlet property="delegate" destination="KGk-i7-Jjw" id="GO4-EB-MG9"/>
</connections>
</textField>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="252" translatesAutoresizingMaskIntoConstraints="NO" id="Lht-i1-s0H">
<rect key="frame" x="60" y="32" width="252" height="14"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" priority="250" id="2X4-TJ-v2V"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.95686274510000002" green="0.26274509800000001" blue="0.21176470589999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="fontName" value="regular12"/>
<userDefinedRuntimeAttribute type="string" keyPath="colorName" value="red"/>
</userDefinedRuntimeAttributes>
</label>
</subviews>
<constraints>
<constraint firstItem="5uK-5Q-cg0" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="6CB-Dy-pnd"/>
<constraint firstItem="krN-k2-9qO" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="M6R-qw-860"/>
<constraint firstAttribute="bottom" secondItem="Lht-i1-s0H" secondAttribute="bottom" constant="12" id="DhN-vK-bTb"/>
<constraint firstItem="Lht-i1-s0H" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="60" id="EIo-KA-vQX"/>
<constraint firstItem="krN-k2-9qO" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="12" id="M6R-qw-860"/>
<constraint firstAttribute="trailing" secondItem="krN-k2-9qO" secondAttribute="trailing" constant="8" id="O2l-xa-4ZO"/>
<constraint firstAttribute="bottom" secondItem="krN-k2-9qO" secondAttribute="bottom" id="mfl-oM-QaP"/>
<constraint firstItem="Lht-i1-s0H" firstAttribute="top" secondItem="krN-k2-9qO" secondAttribute="bottom" id="WLe-gG-Nur"/>
<constraint firstAttribute="trailing" secondItem="Lht-i1-s0H" secondAttribute="trailing" constant="8" id="bkK-l2-xGd"/>
<constraint firstItem="5uK-5Q-cg0" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="mZL-51-0kV"/>
<constraint firstItem="5uK-5Q-cg0" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="ufn-3T-MOd"/>
<constraint firstItem="krN-k2-9qO" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="60" id="w8z-Hi-yGr"/>
</constraints>
@ -58,9 +77,13 @@
<userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="white"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="errorLabel" destination="Lht-i1-s0H" id="N2I-je-OSW"/>
<outlet property="errorLabelTopSpace" destination="WLe-gG-Nur" id="shl-Rd-fU4"/>
<outlet property="icon" destination="5uK-5Q-cg0" id="5du-LU-RmA"/>
<outlet property="labelHeight" destination="2X4-TJ-v2V" id="5jn-qt-Ma7"/>
<outlet property="textField" destination="krN-k2-9qO" id="Fqg-H9-JpU"/>
</connections>
<point key="canvasLocation" x="327" y="351.5"/>
</tableViewCell>
</objects>
</document>

View file

@ -89,6 +89,7 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
vector<MWMEditorSection> m_sections;
map<MWMEditorSection, vector<MWMPlacePageCellType>> m_cells;
osm::EditableMapObject m_mapObject;
vector<pair<MWMPlacePageCellType, NSIndexPath *>> m_invalidCells;
}
- (void)viewDidLoad
@ -161,6 +162,14 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
return;
}
if (!m_invalidCells.empty())
{
auto const & firstInvalid = m_invalidCells.front();
MWMEditorTextTableViewCell * cell = [self.tableView cellForRowAtIndexPath:firstInvalid.second];
[cell.textField becomeFirstResponder];
return;
}
auto & f = GetFramework();
auto const & featureID = m_mapObject.GetID();
NSDictionary * info = @{kStatEditorMWMName : @(featureID.GetMwmName().c_str()),
@ -478,7 +487,22 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
#pragma mark - MWMEditorCellProtocol
- (void)cell:(UITableViewCell *)cell changedText:(NSString *)changeText
- (void)tryToChangeInvalidStateForCell:(MWMEditorTextTableViewCell *)cell
{
[self.tableView beginUpdates];
NSIndexPath * indexPath = [self.tableView indexPathForCell:cell];
m_invalidCells.erase(remove_if(m_invalidCells.begin(), m_invalidCells.end(),
[indexPath](pair<MWMPlacePageCellType, NSIndexPath *> const & p)
{
return [p.second isEqual:indexPath];
}));
[self.tableView endUpdates];
}
- (void)cell:(MWMEditorTextTableViewCell *)cell changedText:(NSString *)changeText
{
NSAssert(changeText != nil, @"String can't be nil!");
NSIndexPath * indexPath = [self.tableView indexPathForCell:cell];
@ -494,6 +518,15 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
case MWMPlacePageCellTypeBuilding: m_mapObject.SetHouseNumber(val); break;
default: NSAssert(false, @"Invalid field for changeText");
}
//TODO: Here we need to process validation's result. Code below performs some UI updates and we should call it
// if validation finish with error.
/*
NSIndexPath * indexPath = [self.tableView indexPathForCell:cell];
m_invalidCells.emplace_back(cellType, indexPath);
[self.tableView reloadRowsAtIndexPaths:@[[self.tableView indexPathForCell:cell]] withRowAnimation:UITableViewRowAnimationFade];
*/
}
- (void)cell:(UITableViewCell *)cell changeSwitch:(BOOL)changeSwitch