Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MRIconView shapeLayer animation and appearance selectors. #87

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions src/Components/MRIconView.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,37 @@

#import <UIKit/UIKit.h>


/**
Base class for icons which are given by an UIBezierPath and drawn with a CAShapeLayer.
Their circular outer border and their line is colored in their tintColor.
*/
@interface MRIconView : UIView

/**
Inner path.
Duration of an animated progress change.

Default is 0.0 which means no animation is used. The recommended value is 0.5.
*/
- (UIBezierPath *)path;
@property (nonatomic, assign) CFTimeInterval animationDuration UI_APPEARANCE_SELECTOR;

/**
The line Width of circle
The line width of the outer circle

Default is 1.0. Must be larger than zero.
*/
@property (nonatomic) CGFloat borderWidth UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign) CGFloat borderWidth UI_APPEARANCE_SELECTOR;

/**
The line width of icon
The line width of the icon

Default is 1.0. Must be larger than zero.
*/
@property (nonatomic) CGFloat lineWidth UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign) CGFloat lineWidth UI_APPEARANCE_SELECTOR;

/**
Inner path.
*/
- (UIBezierPath *)path;

@end

Expand All @@ -41,13 +47,11 @@
Draws a checkmark.
*/
@interface MRCheckmarkIconView : MRIconView

@end


/**
Draws a cross.
*/
@interface MRCrossIconView : MRIconView

@end
52 changes: 43 additions & 9 deletions src/Components/MRIconView.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#import "MRIconView.h"
#import <QuartzCore/QuartzCore.h>

@interface MRIconView ()
@property (nonatomic, assign) BOOL animating;
@end

@implementation MRIconView

Expand Down Expand Up @@ -49,6 +52,7 @@ - (void)commonInit {
self.isAccessibilityElement = YES;

self.shapeLayer.fillColor = UIColor.clearColor.CGColor;
self.animating = NO;

[self tintColorDidChange];
}
Expand All @@ -70,33 +74,64 @@ - (void)setFrame:(CGRect)frame {
self.layer.cornerRadius = frame.size.width / 2.0f;
}

#pragma mark - Properties
#pragma mark - Appearance

- (CGFloat)borderWidth {
return self.layer.borderWidth;
- (CGFloat)borderWidth{
return self.layer.borderWidth;
}

- (void)setBorderWidth:(CGFloat)borderWidth {
self.layer.borderWidth = borderWidth;
self.layer.borderWidth = borderWidth;
}

- (CGFloat)lineWidth {
return self.shapeLayer.lineWidth;
return self.shapeLayer.lineWidth;
}

- (void)setLineWidth:(CGFloat)lineWidth {
self.shapeLayer.lineWidth = lineWidth;
self.shapeLayer.lineWidth = lineWidth;
}

#pragma mark - Animation

@end
- (void)startAnimating {
if (self.animating || self.animationDuration == 0.0) return;
self.animating = YES;
[self addAnimation];
}

- (void)stopAnimating {
if (!self.animating) return;
self.animating = NO;
[self removeAnimation];
}

- (BOOL)isAnimating {
return self.animating;
}

- (void)addAnimation {
CABasicAnimation *drawShapeAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
drawShapeAnimation.duration = self.animationDuration;
drawShapeAnimation.removedOnCompletion = NO;
drawShapeAnimation.fillMode = kCAFillModeBoth;
drawShapeAnimation.fromValue = @(0);
drawShapeAnimation.toValue = @(1);
drawShapeAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[self.shapeLayer addAnimation:drawShapeAnimation forKey:@"DrawShape"];
}

- (void)removeAnimation {
[self.shapeLayer removeAnimationForKey:@"DrawShape"];
}

@end

@implementation MRCheckmarkIconView

- (void)commonInit {
[super commonInit];

self.accessibilityLabel = NSLocalizedString(@"Checkmark", @"Accessibility label for custom rendered checkmark icon");
}

Expand All @@ -113,7 +148,6 @@ - (UIBezierPath *)path {

@end


@implementation MRCrossIconView

- (void)commonInit {
Expand Down
14 changes: 14 additions & 0 deletions src/Components/MRProgressOverlayView.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,20 @@ typedef NS_ENUM(NSUInteger, MRProgressOverlayViewMode){
*/
@property (nonatomic, assign) MRProgressOverlayViewMode mode;

/**
Minimum width to use when laying out the overlay view.

Default value is 150.0.
*/
@property (nonatomic, assign) CGFloat overlayViewMinWidth;

/**
Maximum height to use when laying out the title label.

Default value is MAXFLOAT, which means not set.
*/
@property (nonatomic, assign) CGFloat titleLabelMaxHeight;

/**
Current progress.

Expand Down
8 changes: 5 additions & 3 deletions src/Components/MRProgressOverlayView.m
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ - (void)commonInit {

self.hidden = YES;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.overlayViewMinWidth = 150;
self.titleLabelMaxHeight = MAXFLOAT;

const CGFloat cornerRadius = MRProgressOverlayViewCornerRadius;

Expand Down Expand Up @@ -668,7 +670,7 @@ - (void)manualLayoutSubviews {
const CGFloat dialogPadding = 15;
const CGFloat modePadding = 30;
const CGFloat dialogMargin = 10;
const CGFloat dialogMinWidth = 150;
CGFloat dialogMinWidth = self.overlayViewMinWidth;

const BOOL hasSmallIndicator = self.mode == MRProgressOverlayViewModeIndeterminateSmall
|| self.mode == MRProgressOverlayViewModeIndeterminateSmallDefault;
Expand Down Expand Up @@ -702,9 +704,9 @@ - (void)manualLayoutSubviews {

y += 3;

CGSize titleLabelMaxSize = CGSizeMake(titleLabelMaxWidth, self.bounds.size.height);
CGSize titleLabelMaxSize = CGSizeMake(titleLabelMaxWidth, self.titleLabelMaxHeight != MAXFLOAT ? self.titleLabelMaxHeight : self.bounds.size.height);
CGRect boundingRect = [self.titleLabel.attributedText boundingRectWithSize:titleLabelMaxSize
options:NSStringDrawingUsesLineFragmentOrigin
options:NSStringDrawingUsesLineFragmentOrigin | (self.titleLabelMaxHeight != MAXFLOAT ? NSStringDrawingTruncatesLastVisibleLine : 0)
context:nil];
CGSize titleLabelSize = CGSizeMake(MRCGFloatCeil(boundingRect.size.width),
MRCGFloatCeil(boundingRect.size.height));
Expand Down
3 changes: 3 additions & 0 deletions src/Utils/MRProgressHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ static inline CGRect MRCenterCGSizeInCGRect(CGSize innerRectSize, CGRect outerRe


static inline CGFloat MRRotationForStatusBarOrientation() {
#ifndef APP_EXTENSION
UIInterfaceOrientation orientation = UIApplication.sharedApplication.statusBarOrientation;
if (orientation == UIInterfaceOrientationLandscapeLeft) {
return -M_PI_2;
Expand All @@ -46,5 +47,7 @@ static inline CGFloat MRRotationForStatusBarOrientation() {
} else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
return M_PI;
}
#endif
return 0;
}