This repository has been archived by the owner on Aug 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Feature/checkbox update #15
Merged
pigounet-meli
merged 17 commits into
mercadolibre:develop
from
MLAlexIartsev:feature/checkbox-update
Aug 24, 2018
Merged
Changes from 4 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
7675bdc
Cleanup
MLAlexIartsev f7aad5c
setEnabled public method added
MLAlexIartsev 2534d0e
setEnabled implementation
MLAlexIartsev 4382f16
Uncrustify magic
MLAlexIartsev 0179ae7
Unchecked unselected image fix and interactivity fix.
MLAlexIartsev 39a75a3
Control MLCheckBox in test app
MLAlexIartsev 2e87e4e
Uncrustify magic
MLAlexIartsev 5afec13
Text change so it makes sense
MLAlexIartsev 52afd15
Changing self.userInteractionEnabled to private separate property isE…
MLAlexIartsev 29cccc8
Changed direct color references to three private methods: enabledOnCo…
MLAlexIartsev 2d65e50
Uncrustify
MLAlexIartsev 65a222a
Color correction
MLAlexIartsev 400d33d
Base setEnabled implementation moved to MLBooleanWidget
MLAlexIartsev ae5c831
Uncrustify
MLAlexIartsev 936fa3a
Added MLCheckBox tests checking for enabled state at initiation and s…
MLAlexIartsev c6e7fb9
Uncrustify
MLAlexIartsev 1ea9835
Extra test
MLAlexIartsev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 +10,6 @@ | |
|
||
@interface MLCheckBox : MLBooleanWidget | ||
|
||
- (void)setEnabled:(BOOL)enabled Animated:(BOOL)animated; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,19 +60,49 @@ - (void)layoutSubviews | |
self.checkBoxInternalLayer.frame = self.bounds; | ||
} | ||
|
||
#pragma mark - Public Methods | ||
- (void)setEnabled:(BOOL)enabled Animated:(BOOL)animated | ||
{ | ||
if (self.userInteractionEnabled == enabled) { | ||
return; | ||
} | ||
|
||
self.userInteractionEnabled = enabled; | ||
if (enabled) { | ||
if (self.isBooleanWidgetOn) { | ||
[self fillCheckBoxExternalFromColor:[UIColor ml_meli_mid_grey] ToColor:[UIColor ml_meli_blue] Animated:animated]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Movería los [UIColor ...] a funciones que devuelvan el color para cada estado (checkboxColorOn, checkboxColorOff y checkboxColorDisabled). Así se actualizan desde un solo lugar en caso de querer cambiar. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Claro, yo lo dejé así pero en el fondo estaba pensando que estaría bueno que haya algún config de colores en el futuro. Lo voy a armar con dos métodos así está un pasito más cerca a tener los colores configurables. |
||
[self fillCheckBoxInternalFromColor:[UIColor ml_meli_mid_grey] ToColor:[UIColor ml_meli_blue] FromOpacity:1 ToOpacity:1 Animated:animated]; | ||
[self fillCheckBoxTickAnimated:animated]; | ||
} else { | ||
[self fillCheckBoxExternalFromColor:[UIColor ml_meli_mid_grey] ToColor:[UIColor ml_meli_grey] Animated:animated]; | ||
[self fillCheckBoxInternalFromColor:[UIColor ml_meli_mid_grey] ToColor:[UIColor ml_meli_grey] FromOpacity:0 ToOpacity:0 Animated:animated]; | ||
} | ||
} else { | ||
if (self.isBooleanWidgetOn) { | ||
[self fillCheckBoxExternalFromColor:[UIColor ml_meli_blue] ToColor:[UIColor ml_meli_mid_grey] Animated:animated]; | ||
[self fillCheckBoxInternalFromColor:[UIColor ml_meli_blue] ToColor:[UIColor ml_meli_mid_grey] FromOpacity:1 ToOpacity:1 Animated:animated]; | ||
[self fillCheckBoxTickAnimated:animated]; | ||
} else { | ||
[self fillCheckBoxExternalFromColor:[UIColor ml_meli_grey] ToColor:[UIColor ml_meli_mid_grey] Animated:animated]; | ||
[self fillCheckBoxInternalFromColor:[UIColor ml_meli_grey] ToColor:[UIColor ml_meli_mid_grey] FromOpacity:0 ToOpacity:0 Animated:animated]; | ||
} | ||
} | ||
} | ||
|
||
#pragma mark - Animation | ||
|
||
- (void)setOnBooleanWidgetAnimated:(BOOL)animated | ||
{ | ||
if (self.isBooleanWidgetOn) { | ||
return; | ||
} | ||
|
||
[self fillCheckBoxExternalAnimated:animated]; | ||
[self fillCheckBoxInternalAnimated:animated]; | ||
[self fillCheckBoxInternalFromColor:[UIColor ml_meli_grey] ToColor:[UIColor ml_meli_blue] FromOpacity:0 ToOpacity:1 Animated:animated]; | ||
[self fillCheckBoxTickAnimated:animated]; | ||
} | ||
|
||
- (void)fillCheckBoxExternalAnimated:(BOOL)animated | ||
- (void)fillCheckBoxExternalFromColor:(UIColor *)fromColor ToColor:(UIColor *)toColor Animated:(BOOL)animated | ||
{ | ||
// Set circle layer bounds | ||
self.checkBoxExternalLayer.bounds = CGRectMake(0, 0, CGRectGetHeight(self.frame), CGRectGetWidth(self.frame)); | ||
|
@@ -82,52 +112,40 @@ - (void)fillCheckBoxExternalAnimated:(BOOL)animated | |
self.checkBoxExternalLayer.path = externalFrame.CGPath; | ||
|
||
self.checkBoxExternalLayer.fillColor = [UIColor clearColor].CGColor; | ||
float lineWidth = kMLCheckBoxExternalLineWidth; | ||
|
||
self.checkBoxExternalLayer.lineWidth = lineWidth; | ||
self.checkBoxExternalLayer.lineWidth = kMLCheckBoxExternalLineWidth; | ||
|
||
// Color animation | ||
CABasicAnimation *colorFillAnimation = [CABasicAnimation animationWithKeyPath:@"strokeColor"]; | ||
colorFillAnimation.beginTime = 0; | ||
colorFillAnimation.fromValue = (id)[UIColor ml_meli_grey].CGColor; | ||
colorFillAnimation.toValue = (id)[UIColor ml_meli_blue].CGColor; | ||
colorFillAnimation.fillMode = kCAFillModeForwards; | ||
colorFillAnimation.duration = animated ? kMLCheckBoxAnimationDuration : kMLCheckBoxNotAnimationDuration; | ||
CABasicAnimation *colorFillAnimation = [self createColorFillAnimationFromColor:fromColor ToColor:toColor WithDuration:animated ? kMLCheckBoxAnimationDuration : kMLCheckBoxNotAnimationDuration]; | ||
|
||
[self.checkBoxExternalLayer addAnimation:colorFillAnimation forKey:@"animateFill"]; | ||
|
||
self.checkBoxExternalLayer.strokeColor = [UIColor ml_meli_blue].CGColor; | ||
self.checkBoxExternalLayer.strokeColor = toColor.CGColor; | ||
} | ||
|
||
- (void)fillCheckBoxExternalAnimated:(BOOL)animated | ||
{ | ||
[self fillCheckBoxExternalFromColor:[UIColor ml_meli_grey] ToColor:[UIColor ml_meli_blue] Animated:animated]; | ||
} | ||
|
||
- (void)fillCheckBoxInternalAnimated:(BOOL)animated | ||
- (void)fillCheckBoxInternalFromColor:(UIColor *)fromColor ToColor:(UIColor *)toColor FromOpacity:(float)fromOpacity ToOpacity:(float)toOpacity Animated:(BOOL)animated | ||
{ | ||
// Set circle layer bounds | ||
self.checkBoxInternalLayer.bounds = CGRectMake(0, 0, CGRectGetHeight(self.frame), CGRectGetWidth(self.frame)); | ||
|
||
// Set circle layer path | ||
UIBezierPath *externalFrame = [UIBezierPath bezierPathWithRoundedRect:self.checkBoxExternalLayer.bounds cornerRadius:kMLCheckBoxExternalCornerRadius]; | ||
self.checkBoxInternalLayer.path = externalFrame.CGPath; | ||
|
||
UIBezierPath *internalFrame = [UIBezierPath bezierPathWithRoundedRect:self.checkBoxExternalLayer.bounds cornerRadius:kMLCheckBoxExternalCornerRadius]; | ||
self.checkBoxInternalLayer.path = internalFrame.CGPath; | ||
|
||
self.checkBoxInternalLayer.fillColor = [UIColor ml_meli_blue].CGColor; | ||
self.checkBoxInternalLayer.fillColor = toOpacity == 0 ? [UIColor clearColor].CGColor : toColor.CGColor; | ||
float lineWidth = kMLCheckBoxExternalLineWidth; | ||
|
||
self.checkBoxInternalLayer.lineWidth = lineWidth; | ||
|
||
// Opacity animation | ||
CABasicAnimation *opacityFillAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; | ||
opacityFillAnimation.beginTime = 0; | ||
opacityFillAnimation.fromValue = @0; | ||
opacityFillAnimation.toValue = @1; | ||
opacityFillAnimation.fillMode = kCAFillModeForwards; | ||
CABasicAnimation *opacityFillAnimation = [self createOpacityFillAnimationFromValue:fromOpacity ToValue:toOpacity]; | ||
|
||
// Color animation | ||
CABasicAnimation *colorFillAnimation = [CABasicAnimation animationWithKeyPath:@"strokeColor"]; | ||
colorFillAnimation.beginTime = 0; | ||
colorFillAnimation.fromValue = (id)[UIColor ml_meli_grey].CGColor; | ||
colorFillAnimation.toValue = (id)[UIColor ml_meli_blue].CGColor; | ||
colorFillAnimation.fillMode = kCAFillModeForwards; | ||
CABasicAnimation *colorFillAnimation = [self createColorFillAnimationFromColor:fromColor ToColor:toColor]; | ||
|
||
// Compaund animation | ||
CAAnimationGroup *fillAnimation = [CAAnimationGroup animation]; | ||
|
@@ -136,9 +154,7 @@ - (void)fillCheckBoxInternalAnimated:(BOOL)animated | |
|
||
[self.checkBoxInternalLayer addAnimation:fillAnimation forKey:@"animateFill"]; | ||
|
||
self.checkBoxInternalLayer.strokeColor = [UIColor ml_meli_blue].CGColor; | ||
self.checkBoxInternalLayer.path = internalFrame.CGPath; | ||
self.checkBoxInternalLayer.opacity = 1; | ||
self.checkBoxInternalLayer.strokeColor = toColor.CGColor; | ||
} | ||
|
||
- (void)fillCheckBoxTickAnimated:(BOOL)animated | ||
|
@@ -163,7 +179,6 @@ - (void)fillCheckBoxTickAnimated:(BOOL)animated | |
|
||
// Color animation | ||
CABasicAnimation *pathTickAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; | ||
pathTickAnimation.beginTime = 0; | ||
pathTickAnimation.fromValue = @0.0; | ||
pathTickAnimation.toValue = @1.0; | ||
pathTickAnimation.fillMode = kCAFillModeForwards; | ||
|
@@ -174,79 +189,8 @@ - (void)fillCheckBoxTickAnimated:(BOOL)animated | |
|
||
- (void)setOffBooleanWidgetAnimated:(BOOL)animated | ||
{ | ||
[self clearCheckBoxExternalAnimated:animated]; | ||
[self clearCheckBoxInternalAnimated:animated]; | ||
} | ||
|
||
- (void)clearCheckBoxExternalAnimated:(BOOL)animated | ||
{ | ||
// Set circle layer bounds | ||
self.checkBoxExternalLayer.bounds = CGRectMake(0, 0, CGRectGetHeight(self.frame), CGRectGetWidth(self.frame)); | ||
|
||
// Set circle layer path | ||
UIBezierPath *externalFrame = [UIBezierPath bezierPathWithRoundedRect:self.checkBoxExternalLayer.bounds cornerRadius:kMLCheckBoxExternalCornerRadius]; | ||
|
||
self.checkBoxExternalLayer.path = externalFrame.CGPath; | ||
|
||
self.checkBoxExternalLayer.fillColor = [UIColor clearColor].CGColor; | ||
float lineWidth = kMLCheckBoxExternalLineWidth; | ||
|
||
self.checkBoxExternalLayer.lineWidth = lineWidth; | ||
|
||
// Color animation | ||
CABasicAnimation *colorFillAnimation = [CABasicAnimation animationWithKeyPath:@"strokeColor"]; | ||
colorFillAnimation.beginTime = 0; | ||
colorFillAnimation.fromValue = (id)[UIColor ml_meli_blue].CGColor; | ||
colorFillAnimation.toValue = (id)[UIColor ml_meli_grey].CGColor; | ||
colorFillAnimation.fillMode = kCAFillModeForwards; | ||
colorFillAnimation.duration = animated ? kMLCheckBoxAnimationDuration : kMLCheckBoxNotAnimationDuration; | ||
|
||
[self.checkBoxExternalLayer addAnimation:colorFillAnimation forKey:@"animateFill"]; | ||
|
||
self.checkBoxExternalLayer.strokeColor = [UIColor ml_meli_grey].CGColor; | ||
} | ||
|
||
- (void)clearCheckBoxInternalAnimated:(BOOL)animated | ||
{ | ||
// Set circle layer bounds | ||
self.checkBoxInternalLayer.bounds = CGRectMake(0, 0, CGRectGetHeight(self.frame), CGRectGetWidth(self.frame)); | ||
|
||
// Set circle layer path | ||
UIBezierPath *externalFrame = [UIBezierPath bezierPathWithRoundedRect:self.checkBoxExternalLayer.bounds cornerRadius:kMLCheckBoxExternalCornerRadius]; | ||
|
||
UIBezierPath *internalFrame = [UIBezierPath bezierPathWithRoundedRect:self.checkBoxExternalLayer.bounds cornerRadius:kMLCheckBoxExternalCornerRadius]; | ||
[internalFrame fill]; | ||
|
||
self.checkBoxInternalLayer.path = internalFrame.CGPath; | ||
|
||
self.checkBoxInternalLayer.fillColor = [UIColor clearColor].CGColor; | ||
float lineWidth = kMLCheckBoxExternalLineWidth; | ||
self.checkBoxInternalLayer.lineWidth = lineWidth; | ||
|
||
// Opacity animation | ||
CABasicAnimation *opacityClearAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; | ||
opacityClearAnimation.beginTime = 0; | ||
opacityClearAnimation.fromValue = @1; | ||
opacityClearAnimation.toValue = @0; | ||
opacityClearAnimation.fillMode = kCAFillModeForwards; | ||
|
||
// Color animation | ||
CABasicAnimation *colorClearAnimation = [CABasicAnimation animationWithKeyPath:@"strokeColor"]; | ||
colorClearAnimation.beginTime = 0; | ||
colorClearAnimation.fromValue = (id)[UIColor ml_meli_blue].CGColor; | ||
colorClearAnimation.toValue = (id)[UIColor ml_meli_grey].CGColor; | ||
colorClearAnimation.fillMode = kCAFillModeForwards; | ||
|
||
// Compaund animation | ||
CAAnimationGroup *clearAnimation = [CAAnimationGroup animation]; | ||
clearAnimation.duration = animated ? kMLCheckBoxAnimationDuration : kMLCheckBoxNotAnimationDuration; | ||
[clearAnimation setAnimations:[NSArray arrayWithObjects:colorClearAnimation, opacityClearAnimation, nil]]; | ||
|
||
[self.checkBoxInternalLayer addAnimation:clearAnimation forKey:@"animateClear"]; | ||
|
||
self.checkBoxInternalLayer.strokeColor = [UIColor ml_meli_grey].CGColor; | ||
self.checkBoxInternalLayer.path = externalFrame.CGPath; | ||
self.checkBoxInternalLayer.opacity = 0; | ||
[self fillCheckBoxExternalFromColor:[UIColor ml_meli_blue] ToColor:[UIColor ml_meli_grey] Animated:animated]; | ||
[self fillCheckBoxInternalFromColor:[UIColor ml_meli_blue] ToColor:[UIColor ml_meli_grey] FromOpacity:1 ToOpacity:0 Animated:animated]; | ||
} | ||
|
||
#pragma mark - Tick Positions | ||
|
@@ -274,4 +218,46 @@ - (CGPoint)tickRightPointInRect:(CGRect)rect | |
return CGPointMake(x, y); | ||
} | ||
|
||
- (CABasicAnimation *)createOpacityFillAnimationFromValue:(float)fromValue ToValue:(float)toValue | ||
{ | ||
return [self createOpacityFillAnimationFromValue:fromValue ToValue:toValue WithDuration:0 WithFillMode:kCAFillModeForwards]; | ||
} | ||
|
||
- (CABasicAnimation *)createOpacityFillAnimationFromValue:(float)fromValue ToValue:(float)toValue WithDuration:(double)duration | ||
{ | ||
return [self createOpacityFillAnimationFromValue:fromValue ToValue:toValue WithDuration:duration WithFillMode:kCAFillModeForwards]; | ||
} | ||
|
||
- (CABasicAnimation *)createOpacityFillAnimationFromValue:(float)fromValue ToValue:(float)toValue WithDuration:(double)duration WithFillMode:(NSString *)fillMode | ||
{ | ||
CABasicAnimation *opacityFillAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; | ||
opacityFillAnimation.fromValue = [NSNumber numberWithFloat:fromValue]; | ||
opacityFillAnimation.toValue = [NSNumber numberWithFloat:toValue]; | ||
opacityFillAnimation.duration = duration; | ||
opacityFillAnimation.fillMode = fillMode; | ||
|
||
return opacityFillAnimation; | ||
} | ||
|
||
- (CABasicAnimation *)createColorFillAnimationFromColor:(UIColor *)fromColor ToColor:(UIColor *)toColor WithDuration:(double)duration | ||
{ | ||
return [self createColorFillAnimationFromColor:fromColor ToColor:toColor WithDuration:duration WithFillMode:kCAFillModeForwards]; | ||
} | ||
|
||
- (CABasicAnimation *)createColorFillAnimationFromColor:(UIColor *)fromColor ToColor:(UIColor *)toColor | ||
{ | ||
return [self createColorFillAnimationFromColor:fromColor ToColor:toColor WithDuration:0 WithFillMode:kCAFillModeForwards]; | ||
} | ||
|
||
- (CABasicAnimation *)createColorFillAnimationFromColor:(UIColor *)fromColor ToColor:(UIColor *)toColor WithDuration:(double)duration WithFillMode:(NSString *)fillMode | ||
{ | ||
CABasicAnimation *colorFillAnimation = [CABasicAnimation animationWithKeyPath:@"strokeColor"]; | ||
colorFillAnimation.fromValue = (id)fromColor.CGColor; | ||
colorFillAnimation.toValue = (id)toColor.CGColor; | ||
colorFillAnimation.duration = duration; | ||
colorFillAnimation.fillMode = fillMode; | ||
|
||
return colorFillAnimation; | ||
} | ||
|
||
@end |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usaría un Bool propio del checkbox para mantener el estado enabled/disabled. Nadie te debería modificar el userInteractionEnabled pero podrían y el estado de la ui quedaría raro.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lo que me causa un toque de duda ahí es que si no estoy cambiando el userInteractionEnabled, es posible que la interacción con el componente siga siendo manejada desde BooleanWidget. Lo voy a probar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahí lo probé y parece andar bien. Voy a commitear un cambio con una property BOOL isEnabled