From 9c64935fc16a8058c2db8f598babae5b69b23880 Mon Sep 17 00:00:00 2001 From: Douglas Hill Date: Tue, 19 Jan 2016 14:27:06 +0000 Subject: [PATCH 01/10] Fix floating point precision warnings Casting to CGFloat is ugly, but correct. --- CLTokenInputView/CLTokenInputView/CLTokenInputView.m | 6 +++--- CLTokenInputView/CLTokenInputView/CLTokenView.m | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CLTokenInputView/CLTokenInputView/CLTokenInputView.m b/CLTokenInputView/CLTokenInputView/CLTokenInputView.m index d6c3ff7..f4b7f0a 100644 --- a/CLTokenInputView/CLTokenInputView/CLTokenInputView.m +++ b/CLTokenInputView/CLTokenInputView/CLTokenInputView.m @@ -200,7 +200,7 @@ - (void)repositionViews if (self.fieldView) { CGRect fieldViewRect = self.fieldView.frame; fieldViewRect.origin.x = curX + FIELD_MARGIN_X; - fieldViewRect.origin.y = curY + ((STANDARD_ROW_HEIGHT - CGRectGetHeight(fieldViewRect))/2.0); + fieldViewRect.origin.y = curY + ((STANDARD_ROW_HEIGHT - CGRectGetHeight(fieldViewRect))/(CGFloat)2); self.fieldView.frame = fieldViewRect; curX = CGRectGetMaxX(fieldViewRect) + FIELD_MARGIN_X; @@ -210,7 +210,7 @@ - (void)repositionViews if (!self.fieldLabel.hidden) { CGRect fieldLabelRect = self.fieldLabel.frame; fieldLabelRect.origin.x = curX + FIELD_MARGIN_X; - fieldLabelRect.origin.y = curY + ((STANDARD_ROW_HEIGHT-CGRectGetHeight(fieldLabelRect))/2.0); + fieldLabelRect.origin.y = curY + ((STANDARD_ROW_HEIGHT-CGRectGetHeight(fieldLabelRect))/(CGFloat)2); self.fieldLabel.frame = fieldLabelRect; curX = CGRectGetMaxX(fieldLabelRect) + FIELD_MARGIN_X; @@ -242,7 +242,7 @@ - (void)repositionViews tokenRect.origin.x = curX; // Center our tokenView vertially within STANDARD_ROW_HEIGHT - tokenRect.origin.y = curY + ((STANDARD_ROW_HEIGHT-CGRectGetHeight(tokenRect))/2.0); + tokenRect.origin.y = curY + ((STANDARD_ROW_HEIGHT-CGRectGetHeight(tokenRect))/(CGFloat)2); tokenView.frame = tokenRect; curX = CGRectGetMaxX(tokenRect) + HSPACE; diff --git a/CLTokenInputView/CLTokenInputView/CLTokenView.m b/CLTokenInputView/CLTokenInputView/CLTokenView.m index 2cffcf5..793c4c3 100644 --- a/CLTokenInputView/CLTokenInputView/CLTokenView.m +++ b/CLTokenInputView/CLTokenInputView/CLTokenView.m @@ -35,7 +35,7 @@ - (id)initWithToken:(CLToken *)token font:(nullable UIFont *)font { self = [super initWithFrame:CGRectZero]; if (self) { - UIColor *tintColor = [UIColor colorWithRed:0.0823 green:0.4941 blue:0.9843 alpha:1.0]; + UIColor *tintColor = [UIColor colorWithRed:0.0823f green:0.4941f blue:0.9843f alpha:1]; if ([self respondsToSelector:@selector(tintColor)]) { tintColor = self.tintColor; } @@ -82,14 +82,14 @@ - (id)initWithToken:(CLToken *)token font:(nullable UIFont *)font - (CGSize)intrinsicContentSize { CGSize labelIntrinsicSize = self.selectedLabel.intrinsicContentSize; - return CGSizeMake(labelIntrinsicSize.width+(2.0*PADDING_X), labelIntrinsicSize.height+(2.0*PADDING_Y)); + return CGSizeMake(labelIntrinsicSize.width + ((CGFloat)2 * PADDING_X), labelIntrinsicSize.height + ((CGFloat)2 * PADDING_Y)); } - (CGSize)sizeThatFits:(CGSize)size { - CGSize fittingSize = CGSizeMake(size.width-(2.0*PADDING_X), size.height-(2.0*PADDING_Y)); + CGSize fittingSize = CGSizeMake(size.width - ((CGFloat)2 * PADDING_X), size.height - ((CGFloat)2 * PADDING_Y)); CGSize labelSize = [self.selectedLabel sizeThatFits:fittingSize]; - return CGSizeMake(labelSize.width+(2.0*PADDING_X), labelSize.height+(2.0*PADDING_Y)); + return CGSizeMake(labelSize.width + ((CGFloat)2 * PADDING_X), labelSize.height + ((CGFloat)2 * PADDING_Y)); } From 4fb887b1c4bb8d719a3bba414f236f314f80fea7 Mon Sep 17 00:00:00 2001 From: Douglas Hill Date: Tue, 19 Jan 2016 14:27:42 +0000 Subject: [PATCH 02/10] Fix weak warning The weak variable was accessed more than once. --- .../CLTokenInputView/CLBackspaceDetectingTextField.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CLTokenInputView/CLTokenInputView/CLBackspaceDetectingTextField.m b/CLTokenInputView/CLTokenInputView/CLBackspaceDetectingTextField.m index 9bfcb93..1709127 100644 --- a/CLTokenInputView/CLTokenInputView/CLBackspaceDetectingTextField.m +++ b/CLTokenInputView/CLTokenInputView/CLBackspaceDetectingTextField.m @@ -24,8 +24,9 @@ - (id)initWithFrame:(CGRect)frame // Listen for the deleteBackward method from UIKeyInput protocol - (void)deleteBackward { - if ([self.delegate respondsToSelector:@selector(textFieldDidDeleteBackwards:)]) { - [self.delegate textFieldDidDeleteBackwards:self]; + NSObject *delegate = self.delegate; + if ([delegate respondsToSelector:@selector(textFieldDidDeleteBackwards:)]) { + [delegate textFieldDidDeleteBackwards:self]; } // Call super afterwards, so the -text property will return text // prior to the delete From eb739f57e26a4eef0370dbeffb12b1c05b4161cd Mon Sep 17 00:00:00 2001 From: Douglas Hill Date: Tue, 19 Jan 2016 14:28:01 +0000 Subject: [PATCH 03/10] Fix literal format string warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this case it’s not a problem anyway. Restructuring the code like this happens to not result in the warning. --- CLTokenInputView/CLTokenInputView/CLTokenView.m | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/CLTokenInputView/CLTokenInputView/CLTokenView.m b/CLTokenInputView/CLTokenInputView/CLTokenView.m index 793c4c3..bc4c967 100644 --- a/CLTokenInputView/CLTokenInputView/CLTokenView.m +++ b/CLTokenInputView/CLTokenInputView/CLTokenView.m @@ -177,11 +177,7 @@ - (void)setSelected:(BOOL)selected animated:(BOOL)animated - (void)updateLabelAttributedText { // Configure for the token, unselected shows "[displayText]," and selected is "[displayText]" - NSString *format = UNSELECTED_LABEL_FORMAT; - if (self.hideUnselectedComma) { - format = UNSELECTED_LABEL_NO_COMMA_FORMAT; - } - NSString *labelString = [NSString stringWithFormat:format, self.displayText]; + NSString *labelString = [NSString stringWithFormat:self.hideUnselectedComma ? UNSELECTED_LABEL_NO_COMMA_FORMAT : UNSELECTED_LABEL_FORMAT, self.displayText]; NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:labelString attributes:@{NSFontAttributeName : self.label.font, From 7ad4caa3a4c7e85b0c618348f7c6a847c62cfc06 Mon Sep 17 00:00:00 2001 From: Douglas Hill Date: Tue, 19 Jan 2016 14:28:34 +0000 Subject: [PATCH 04/10] Fix implicit self references in block warning The instance variable and parameter are equal, so we can simply use the parameter instead. --- CLTokenInputView/CLTokenInputView/CLTokenView.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CLTokenInputView/CLTokenInputView/CLTokenView.m b/CLTokenInputView/CLTokenInputView/CLTokenView.m index bc4c967..bf923a9 100644 --- a/CLTokenInputView/CLTokenInputView/CLTokenView.m +++ b/CLTokenInputView/CLTokenInputView/CLTokenView.m @@ -147,9 +147,9 @@ - (void)setSelected:(BOOL)selected animated:(BOOL)animated } else if (!selected && self.isFirstResponder) { [self resignFirstResponder]; } - CGFloat selectedAlpha = (_selected ? 1.0 : 0.0); + CGFloat selectedAlpha = (selected ? 1.0 : 0.0); if (animated) { - if (_selected) { + if (selected) { self.selectedBackgroundView.alpha = 0.0; self.selectedBackgroundView.hidden = NO; self.selectedLabel.alpha = 0.0; @@ -159,14 +159,14 @@ - (void)setSelected:(BOOL)selected animated:(BOOL)animated self.selectedBackgroundView.alpha = selectedAlpha; self.selectedLabel.alpha = selectedAlpha; } completion:^(BOOL finished) { - if (!_selected) { + if (!selected) { self.selectedBackgroundView.hidden = YES; self.selectedLabel.hidden = YES; } }]; } else { - self.selectedBackgroundView.hidden = !_selected; - self.selectedLabel.hidden = !_selected; + self.selectedBackgroundView.hidden = !selected; + self.selectedLabel.hidden = !selected; } } From cb22e44e7a4cf17c86d108db484519a4e316f6e9 Mon Sep 17 00:00:00 2001 From: Douglas Hill Date: Tue, 19 Jan 2016 14:29:06 +0000 Subject: [PATCH 05/10] Fix pointer nullability mismatch Easiest way without casting is to use the parameter, since its nullability is unspecified, and the parameter is equal to the instance variable. --- CLTokenInputView/CLTokenInputView/CLTokenInputView.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CLTokenInputView/CLTokenInputView/CLTokenInputView.m b/CLTokenInputView/CLTokenInputView/CLTokenInputView.m index f4b7f0a..0fb8699 100644 --- a/CLTokenInputView/CLTokenInputView/CLTokenInputView.m +++ b/CLTokenInputView/CLTokenInputView/CLTokenInputView.m @@ -509,8 +509,8 @@ - (void)setFieldView:(UIView *)fieldView } [_fieldView removeFromSuperview]; _fieldView = fieldView; - if (_fieldView != nil) { - [self addSubview:_fieldView]; + if (fieldView != nil) { + [self addSubview:fieldView]; } [self repositionViews]; } @@ -532,8 +532,8 @@ - (void)setAccessoryView:(UIView *)accessoryView [_accessoryView removeFromSuperview]; _accessoryView = accessoryView; - if (_accessoryView != nil) { - [self addSubview:_accessoryView]; + if (accessoryView != nil) { + [self addSubview:accessoryView]; } [self repositionViews]; } From 3ff2d979a42462060e2a9244536bdacd3aa743bc Mon Sep 17 00:00:00 2001 From: Douglas Hill Date: Tue, 19 Jan 2016 14:30:12 +0000 Subject: [PATCH 06/10] Use static function for shared initialisation This will work better if something subclasses CLTokenInputView and also wants shared initialisation, and happens to use the same selector. --- CLTokenInputView/CLTokenInputView/CLTokenInputView.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CLTokenInputView/CLTokenInputView/CLTokenInputView.m b/CLTokenInputView/CLTokenInputView/CLTokenInputView.m index 0fb8699..8f04610 100644 --- a/CLTokenInputView/CLTokenInputView/CLTokenInputView.m +++ b/CLTokenInputView/CLTokenInputView/CLTokenInputView.m @@ -38,7 +38,7 @@ @interface CLTokenInputView () Date: Tue, 19 Jan 2016 14:30:45 +0000 Subject: [PATCH 07/10] Change to slightly better distributed hash --- CLTokenInputView/CLTokenInputView/CLToken.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLTokenInputView/CLTokenInputView/CLToken.m b/CLTokenInputView/CLTokenInputView/CLToken.m index aee550c..331a02a 100644 --- a/CLTokenInputView/CLTokenInputView/CLToken.m +++ b/CLTokenInputView/CLTokenInputView/CLToken.m @@ -39,7 +39,7 @@ - (BOOL)isEqual:(id)object - (NSUInteger)hash { - return self.displayText.hash + self.context.hash; + return self.displayText.hash ^ self.context.hash; } @end From cc273a09a9356ebae7e2cb4b55a9f0ce319a40d0 Mon Sep 17 00:00:00 2001 From: Douglas Hill Date: Tue, 19 Jan 2016 14:31:37 +0000 Subject: [PATCH 08/10] Copy display text set at initialisation It would normally be expects for this parameter to follow the same ownership rules as the property is relates to. --- CLTokenInputView/CLTokenInputView/CLToken.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLTokenInputView/CLTokenInputView/CLToken.m b/CLTokenInputView/CLTokenInputView/CLToken.m index 331a02a..2cc2f1c 100644 --- a/CLTokenInputView/CLTokenInputView/CLToken.m +++ b/CLTokenInputView/CLTokenInputView/CLToken.m @@ -14,7 +14,7 @@ - (id)initWithDisplayText:(NSString *)displayText context:(NSObject *)context { self = [super init]; if (self) { - self.displayText = displayText; + self.displayText = [displayText copy]; self.context = context; } return self; From a5f8a9d3bc4943e6bb1ea8c3cf7d84fec5893a0c Mon Sep 17 00:00:00 2001 From: Douglas Hill Date: Tue, 19 Jan 2016 20:55:48 +0000 Subject: [PATCH 09/10] =?UTF-8?q?Use=20UIKit=E2=80=99s=20layout=20system?= =?UTF-8?q?=20properly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoid laying out the view more than once per runloop cycle. --- .../CLTokenInputView/CLTokenInputView.m | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/CLTokenInputView/CLTokenInputView/CLTokenInputView.m b/CLTokenInputView/CLTokenInputView/CLTokenInputView.m index 8f04610..0aa243e 100644 --- a/CLTokenInputView/CLTokenInputView/CLTokenInputView.m +++ b/CLTokenInputView/CLTokenInputView/CLTokenInputView.m @@ -67,7 +67,6 @@ static void commonInit(CLTokenInputView *self) self.fieldLabel.hidden = YES; self.intrinsicContentHeight = STANDARD_ROW_HEIGHT; - [self repositionViews]; } - (id)initWithFrame:(CGRect)frame @@ -132,7 +131,7 @@ - (void)addToken:(CLToken *)token [self onTextFieldDidChange:self.textField]; [self updatePlaceholderTextVisibility]; - [self repositionViews]; + [self setNeedsLayout]; } - (void)removeToken:(CLToken *)token @@ -158,7 +157,7 @@ - (void)removeTokenAtIndex:(NSInteger)index [self.delegate tokenInputView:self didRemoveToken:removedToken]; } [self updatePlaceholderTextVisibility]; - [self repositionViews]; + [self setNeedsLayout]; } - (NSArray *)allTokens @@ -185,8 +184,10 @@ - (CLToken *)tokenizeTextfieldText #pragma mark - Updating/Repositioning Views -- (void)repositionViews +- (void)layoutSubviews { + [super layoutSubviews]; + CGRect bounds = self.bounds; CGFloat rightBoundary = CGRectGetWidth(bounds) - PADDING_RIGHT; CGFloat firstLineRightBoundary = rightBoundary; @@ -290,13 +291,6 @@ - (void)updatePlaceholderTextVisibility } -- (void)layoutSubviews -{ - [super layoutSubviews]; - [self repositionViews]; -} - - #pragma mark - CLBackspaceDetectingTextFieldDelegate - (void)textFieldDidDeleteBackwards:(UITextField *)textField @@ -493,7 +487,7 @@ - (void)setFieldName:(NSString *)fieldName } if (oldFieldName == nil || ![oldFieldName isEqualToString:fieldName]) { - [self repositionViews]; + [self setNeedsLayout]; } } @@ -512,7 +506,7 @@ - (void)setFieldView:(UIView *)fieldView if (fieldView != nil) { [self addSubview:fieldView]; } - [self repositionViews]; + [self setNeedsLayout]; } - (void)setPlaceholderText:(NSString *)placeholderText @@ -535,7 +529,7 @@ - (void)setAccessoryView:(UIView *)accessoryView if (accessoryView != nil) { [self addSubview:accessoryView]; } - [self repositionViews]; + [self setNeedsLayout]; } From 31555a75a4b984d9c4de9162d4bb3ed894df3585 Mon Sep 17 00:00:00 2001 From: Douglas Hill Date: Tue, 19 Jan 2016 21:29:45 +0000 Subject: [PATCH 10/10] Use isEqualToString: instead of pointer equality The comparison will take slightly longer, but this will avoid some cases of updating the view unnecessarily. --- CLTokenInputView/CLTokenInputView/CLTokenInputView.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CLTokenInputView/CLTokenInputView/CLTokenInputView.m b/CLTokenInputView/CLTokenInputView/CLTokenInputView.m index 0aa243e..cd494ff 100644 --- a/CLTokenInputView/CLTokenInputView/CLTokenInputView.m +++ b/CLTokenInputView/CLTokenInputView/CLTokenInputView.m @@ -470,7 +470,7 @@ - (void)endEditing - (void)setFieldName:(NSString *)fieldName { - if (_fieldName == fieldName) { + if ([_fieldName isEqualToString:fieldName]) { return; } NSString *oldFieldName = _fieldName; @@ -511,7 +511,7 @@ - (void)setFieldView:(UIView *)fieldView - (void)setPlaceholderText:(NSString *)placeholderText { - if (_placeholderText == placeholderText) { + if ([_placeholderText isEqualToString:placeholderText]) { return; } _placeholderText = placeholderText;