From f19ea3c8fe5d1f1b278511e8c5aa4d83f44814ef Mon Sep 17 00:00:00 2001 From: Toni Moeckel Date: Tue, 18 Feb 2014 14:58:08 +0100 Subject: [PATCH 01/21] Create iOS7 compatibility with fallback for iOS6 --- Demo/KoaPullToRefresh.xcodeproj/project.pbxproj | 4 ++-- Demo/KoaPullToRefresh/KoaPullToRefresh.m | 14 +++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj b/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj index 3b7504b..9e67ccc 100644 --- a/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj +++ b/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj @@ -309,7 +309,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "KoaPullToRefresh/KoaPullToRefresh-Prefix.pch"; INFOPLIST_FILE = "KoaPullToRefresh/KoaPullToRefresh-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -321,7 +321,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "KoaPullToRefresh/KoaPullToRefresh-Prefix.pch"; INFOPLIST_FILE = "KoaPullToRefresh/KoaPullToRefresh-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/Demo/KoaPullToRefresh/KoaPullToRefresh.m b/Demo/KoaPullToRefresh/KoaPullToRefresh.m index 2bfbbc8..4b03189 100644 --- a/Demo/KoaPullToRefresh/KoaPullToRefresh.m +++ b/Demo/KoaPullToRefresh/KoaPullToRefresh.m @@ -188,7 +188,19 @@ - (void)layoutSubviews self.titleLabel.text = [self.titles objectAtIndex:self.state]; //Set title frame - CGSize titleSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) lineBreakMode:self.titleLabel.lineBreakMode]; + + CGSize titleSize; + if ([self.titleLabel.text respondsToSelector:@selector(sizeWithAttributes:)]) { + titleSize = [self.titleLabel.text boundingRectWithSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: self.titleLabel.font} context:nil].size; + } else { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + titleSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) lineBreakMode:self.titleLabel.lineBreakMode]; +#pragma clang diagnostic pop + } + + + CGFloat titleY = KoaPullToRefreshViewHeight - KoaPullToRefreshViewHeightShowed - titleSize.height - KoaPullToRefreshViewTitleBottomMargin; [self.titleLabel setFrame:CGRectIntegral(CGRectMake(0, titleY, self.frame.size.width, titleSize.height))]; From 9e6d4d5999f6c23f91b77c9cd5e2ed4ce0209039 Mon Sep 17 00:00:00 2001 From: Toni Moeckel Date: Tue, 18 Feb 2014 15:01:29 +0100 Subject: [PATCH 02/21] Replaced demo lib with original lib --- .../project.pbxproj | 21 +- Demo/KoaPullToRefresh/KoaPullToRefresh.h | 52 -- Demo/KoaPullToRefresh/KoaPullToRefresh.m | 451 ------------------ KoaPullToRefresh/KoaPullToRefresh.m | 60 ++- 4 files changed, 51 insertions(+), 533 deletions(-) delete mode 100644 Demo/KoaPullToRefresh/KoaPullToRefresh.h delete mode 100644 Demo/KoaPullToRefresh/KoaPullToRefresh.m diff --git a/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj b/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj index 9e67ccc..cf94410 100644 --- a/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj +++ b/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj @@ -18,7 +18,6 @@ 555AC081173B93B0001EAC94 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 555AC080173B93B0001EAC94 /* Default-568h@2x.png */; }; 555AC084173B93B0001EAC94 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 555AC083173B93B0001EAC94 /* ViewController.m */; }; 555AC087173B93B0001EAC94 /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 555AC085173B93B0001EAC94 /* ViewController.xib */; }; - 555AC08F173B9DFE001EAC94 /* KoaPullToRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 555AC08E173B9DFE001EAC94 /* KoaPullToRefresh.m */; }; 555AC091173BABE7001EAC94 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 555AC090173BABE7001EAC94 /* QuartzCore.framework */; }; 555AC095173BB30D001EAC94 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 555AC092173BB30D001EAC94 /* OpenSans-Bold.ttf */; }; 555AC096173BB30D001EAC94 /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 555AC093173BB30D001EAC94 /* OpenSans-Regular.ttf */; }; @@ -26,6 +25,7 @@ 55D8EC7A173D053300006E3F /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 55D8EC77173D053300006E3F /* FontAwesome.ttf */; }; 55D8EC7B173D053300006E3F /* UIFont+FontAwesome.m in Sources */ = {isa = PBXBuildFile; fileRef = 55D8EC79173D053300006E3F /* UIFont+FontAwesome.m */; }; 55D8EC7E173D05E400006E3F /* NSString+FontAwesome.m in Sources */ = {isa = PBXBuildFile; fileRef = 55D8EC7D173D05E400006E3F /* NSString+FontAwesome.m */; }; + 89893D4F18B39EEB00DDA2BF /* KoaPullToRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 89893D4E18B39EEB00DDA2BF /* KoaPullToRefresh.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -45,8 +45,6 @@ 555AC082173B93B0001EAC94 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 555AC083173B93B0001EAC94 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 555AC086173B93B0001EAC94 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController.xib; sourceTree = ""; }; - 555AC08D173B9DFE001EAC94 /* KoaPullToRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KoaPullToRefresh.h; sourceTree = ""; }; - 555AC08E173B9DFE001EAC94 /* KoaPullToRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KoaPullToRefresh.m; sourceTree = ""; }; 555AC090173BABE7001EAC94 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 555AC092173BB30D001EAC94 /* OpenSans-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "OpenSans-Bold.ttf"; sourceTree = ""; }; 555AC093173BB30D001EAC94 /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "OpenSans-Regular.ttf"; sourceTree = ""; }; @@ -56,6 +54,8 @@ 55D8EC79173D053300006E3F /* UIFont+FontAwesome.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+FontAwesome.m"; sourceTree = ""; }; 55D8EC7C173D05E400006E3F /* NSString+FontAwesome.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+FontAwesome.h"; sourceTree = ""; }; 55D8EC7D173D05E400006E3F /* NSString+FontAwesome.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+FontAwesome.m"; sourceTree = ""; }; + 89893D4D18B39EEB00DDA2BF /* KoaPullToRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KoaPullToRefresh.h; sourceTree = ""; }; + 89893D4E18B39EEB00DDA2BF /* KoaPullToRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KoaPullToRefresh.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -76,6 +76,7 @@ 555AC05E173B93B0001EAC94 = { isa = PBXGroup; children = ( + 89893D4C18B39EEB00DDA2BF /* KoaPullToRefresh-lib */, 555AC070173B93B0001EAC94 /* KoaPullToRefresh */, 555AC069173B93B0001EAC94 /* Frameworks */, 555AC068173B93B0001EAC94 /* Products */, @@ -109,8 +110,6 @@ 555AC082173B93B0001EAC94 /* ViewController.h */, 555AC083173B93B0001EAC94 /* ViewController.m */, 555AC085173B93B0001EAC94 /* ViewController.xib */, - 555AC08D173B9DFE001EAC94 /* KoaPullToRefresh.h */, - 555AC08E173B9DFE001EAC94 /* KoaPullToRefresh.m */, 55D8EC76173D053300006E3F /* Resources */, 555AC071173B93B0001EAC94 /* Supporting Files */, ); @@ -146,6 +145,16 @@ path = Resources; sourceTree = ""; }; + 89893D4C18B39EEB00DDA2BF /* KoaPullToRefresh-lib */ = { + isa = PBXGroup; + children = ( + 89893D4D18B39EEB00DDA2BF /* KoaPullToRefresh.h */, + 89893D4E18B39EEB00DDA2BF /* KoaPullToRefresh.m */, + ); + name = "KoaPullToRefresh-lib"; + path = ../KoaPullToRefresh; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -219,7 +228,7 @@ 555AC077173B93B0001EAC94 /* main.m in Sources */, 555AC07B173B93B0001EAC94 /* AppDelegate.m in Sources */, 555AC084173B93B0001EAC94 /* ViewController.m in Sources */, - 555AC08F173B9DFE001EAC94 /* KoaPullToRefresh.m in Sources */, + 89893D4F18B39EEB00DDA2BF /* KoaPullToRefresh.m in Sources */, 55D8EC7B173D053300006E3F /* UIFont+FontAwesome.m in Sources */, 55D8EC7E173D05E400006E3F /* NSString+FontAwesome.m in Sources */, ); diff --git a/Demo/KoaPullToRefresh/KoaPullToRefresh.h b/Demo/KoaPullToRefresh/KoaPullToRefresh.h deleted file mode 100644 index dd1dae8..0000000 --- a/Demo/KoaPullToRefresh/KoaPullToRefresh.h +++ /dev/null @@ -1,52 +0,0 @@ -// -// KoaPullToRefresh.h -// KoaPullToRefresh -// -// Created by Sergi Gracia on 09/05/13. -// Copyright (c) 2013 Sergi Gracia. All rights reserved. -// - -#import -#import -#import "NSString+FontAwesome.h" -#import "UIFont+FontAwesome.h" - -@class KoaPullToRefreshView; - -@interface UIScrollView (KoaPullToRefresh) - -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler; -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler withBackgroundColor:(UIColor *)customBackgroundColor; -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler withBackgroundColor:(UIColor *)customBackgroundColor withPullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed; - -@property (nonatomic, strong) KoaPullToRefreshView *pullToRefreshView; -@property (nonatomic, assign) BOOL showsPullToRefresh; - -@end - -enum { - KoaPullToRefreshStateStopped = 0, - KoaPullToRefreshStateTriggered, - KoaPullToRefreshStateLoading, - KoaPullToRefreshStateAll = 10 -}; - -typedef NSUInteger KoaPullToRefreshState; - - -@interface KoaPullToRefreshView : UIView - -@property (nonatomic, strong) UIColor *arrowColor; -@property (nonatomic, strong) UIColor *textColor; -@property (nonatomic, strong) UIFont *textFont; -@property (nonatomic, strong, readonly) UILabel *titleLabel; -@property (nonatomic, strong, readonly) UILabel *loaderLabel; -@property (nonatomic, strong, readonly) NSString *fontAwesomeIcon; -@property (nonatomic, readonly) KoaPullToRefreshState state; - -- (void)setTitle:(NSString *)title forState:(KoaPullToRefreshState)state; -- (void)setFontAwesomeIcon:(NSString *)fontAwesomeIcon; -- (void)startAnimating; -- (void)stopAnimating; - -@end diff --git a/Demo/KoaPullToRefresh/KoaPullToRefresh.m b/Demo/KoaPullToRefresh/KoaPullToRefresh.m deleted file mode 100644 index 4b03189..0000000 --- a/Demo/KoaPullToRefresh/KoaPullToRefresh.m +++ /dev/null @@ -1,451 +0,0 @@ -// -// KoaPullToRefresh.m -// KoaPullToRefresh -// -// Created by Sergi Gracia on 09/05/13. -// Copyright (c) 2013 Sergi Gracia. All rights reserved. -// - -#import "KoaPullToRefresh.h" -#import - -#define fequal(a,b) (fabs((a) - (b)) < FLT_EPSILON) -#define fequalzero(a) (fabs(a) < FLT_EPSILON) - -static CGFloat KoaPullToRefreshViewHeight = 82; -static CGFloat KoaPullToRefreshViewHeightShowed = 0; -static CGFloat KoaPullToRefreshViewTitleBottomMargin = 12; - -@interface KoaPullToRefreshView () - -@property (nonatomic, copy) void (^pullToRefreshActionHandler)(void); -@property (nonatomic, strong, readwrite) UILabel *titleLabel; -@property (nonatomic, strong, readwrite) UILabel *loaderLabel; -@property (nonatomic, readwrite) KoaPullToRefreshState state; -@property (nonatomic, strong) NSMutableArray *titles; -@property (nonatomic, weak) UIScrollView *scrollView; -@property (nonatomic, readwrite) CGFloat originalTopInset; -@property (nonatomic, readwrite) CGFloat originalBottomInset; -@property (nonatomic, assign) BOOL wasTriggeredByUser; -@property (nonatomic, assign) BOOL showsPullToRefresh; -@property(nonatomic, assign) BOOL isObserving; - -- (void)resetScrollViewContentInset; -- (void)setScrollViewContentInsetForLoading; -- (void)setScrollViewContentInset:(UIEdgeInsets)insets; - -@end - -#pragma mark - UIScrollView (KoaPullToRefresh) -#import - -static char UIScrollViewPullToRefreshView; - -@implementation UIScrollView (KoaPullToRefresh) -@dynamic pullToRefreshView, showsPullToRefresh; - -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler { - [self addPullToRefreshWithActionHandler:actionHandler withBackgroundColor:[UIColor grayColor]]; -} - -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler - withBackgroundColor:(UIColor *)customBackgroundColor { - [self addPullToRefreshWithActionHandler:actionHandler withBackgroundColor:customBackgroundColor withPullToRefreshHeightShowed:KoaPullToRefreshViewHeightShowed]; -} - -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler - withBackgroundColor:(UIColor *)customBackgroundColor - withPullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed { - - //KoaPullToRefreshViewHeight = pullToRefreshHeight; - KoaPullToRefreshViewHeightShowed = pullToRefreshHeightShowed; - KoaPullToRefreshViewTitleBottomMargin += pullToRefreshHeightShowed; - - [self setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed, self.contentInset.left, self.contentInset.bottom, self.contentInset.right)]; - - if (!self.pullToRefreshView) { - - //Initial y position - CGFloat yOrigin = -KoaPullToRefreshViewHeight; - - //Put background extra to fill top white space - UIView *backgroundExtra = [[UIView alloc] initWithFrame:CGRectMake(0, -KoaPullToRefreshViewHeight*8, self.bounds.size.width, KoaPullToRefreshViewHeight*8)]; - [backgroundExtra setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; - [backgroundExtra setBackgroundColor:customBackgroundColor]; - [self addSubview:backgroundExtra]; - - //Init pull to refresh view - KoaPullToRefreshView *view = [[KoaPullToRefreshView alloc] initWithFrame:CGRectMake(0, yOrigin, self.bounds.size.width, KoaPullToRefreshViewHeight + KoaPullToRefreshViewHeightShowed)]; - view.pullToRefreshActionHandler = actionHandler; - view.scrollView = self; - view.backgroundColor = customBackgroundColor; - [self addSubview:view]; - - view.originalTopInset = self.contentInset.top; - view.originalBottomInset = self.contentInset.bottom; - - self.pullToRefreshView = view; - self.showsPullToRefresh = YES; - } -} - -- (void)setPullToRefreshView:(KoaPullToRefreshView *)pullToRefreshView { - [self willChangeValueForKey:@"KoaPullToRefreshView"]; - objc_setAssociatedObject(self, &UIScrollViewPullToRefreshView, - pullToRefreshView, - OBJC_ASSOCIATION_ASSIGN); - [self didChangeValueForKey:@"KoaPullToRefreshView"]; -} - -- (KoaPullToRefreshView *)pullToRefreshView { - return objc_getAssociatedObject(self, &UIScrollViewPullToRefreshView); -} - -- (void)setShowsPullToRefresh:(BOOL)showsPullToRefresh { - self.pullToRefreshView.hidden = !showsPullToRefresh; - - if(!showsPullToRefresh) { - if (self.pullToRefreshView.isObserving) { - [self removeObserver:self.pullToRefreshView forKeyPath:@"contentOffset"]; - [self removeObserver:self.pullToRefreshView forKeyPath:@"frame"]; - [self.pullToRefreshView resetScrollViewContentInset]; - self.pullToRefreshView.isObserving = NO; - } - }else { - if (!self.pullToRefreshView.isObserving) { - [self addObserver:self.pullToRefreshView forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil]; - [self addObserver:self.pullToRefreshView forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil]; - [self addObserver:self.pullToRefreshView forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil]; - self.pullToRefreshView.isObserving = YES; - - CGFloat yOrigin = -KoaPullToRefreshViewHeight; - self.pullToRefreshView.frame = CGRectMake(0, yOrigin, self.bounds.size.width, KoaPullToRefreshViewHeight + KoaPullToRefreshViewHeightShowed); - } - } -} - -- (BOOL)showsPullToRefresh { - return !self.pullToRefreshView.hidden; -} - -@end - - -#pragma mark - KoaPullToRefresh -@implementation KoaPullToRefreshView - -@synthesize pullToRefreshActionHandler, arrowColor, textColor, textFont; -@synthesize state = _state; -@synthesize scrollView = _scrollView; -@synthesize showsPullToRefresh = _showsPullToRefresh; -@synthesize titleLabel = _titleLabel; -@synthesize loaderLabel = _loaderLabel; -@synthesize fontAwesomeIcon = _fontAwesomeIcon; - -- (id)initWithFrame:(CGRect)frame { - if(self = [super initWithFrame:frame]) { - - // default styling values - self.textColor = [UIColor darkGrayColor]; - self.backgroundColor = [UIColor whiteColor]; - self.autoresizingMask = UIViewAutoresizingFlexibleWidth; - self.state = KoaPullToRefreshStateStopped; - [self.titleLabel setTextAlignment:NSTextAlignmentCenter]; - [self.loaderLabel setTextAlignment:NSTextAlignmentLeft]; - - self.titles = [NSMutableArray arrayWithObjects: NSLocalizedString(@"Pull",), - NSLocalizedString(@"Release",), - NSLocalizedString(@"Loading",), - nil]; - - self.wasTriggeredByUser = YES; - } - return self; -} - -- (void)willMoveToSuperview:(UIView *)newSuperview { - if (self.superview && newSuperview == nil) { - UIScrollView *scrollView = (UIScrollView *)self.superview; - if (scrollView.showsPullToRefresh) { - if (self.isObserving) { - //If enter this branch, it is the moment just before "KoaPullToRefreshView's dealloc", so remove observer here - [scrollView removeObserver:self forKeyPath:@"contentOffset"]; - [scrollView removeObserver:self forKeyPath:@"contentSize"]; - [scrollView removeObserver:self forKeyPath:@"frame"]; - self.isObserving = NO; - } - } - } -} - -- (void)layoutSubviews -{ - CGFloat leftViewWidth = 60; - CGFloat margin = 10; - CGFloat labelMaxWidth = self.bounds.size.width - margin - leftViewWidth; - - //Set title text - self.titleLabel.text = [self.titles objectAtIndex:self.state]; - - //Set title frame - - CGSize titleSize; - if ([self.titleLabel.text respondsToSelector:@selector(sizeWithAttributes:)]) { - titleSize = [self.titleLabel.text boundingRectWithSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: self.titleLabel.font} context:nil].size; - } else { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - titleSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) lineBreakMode:self.titleLabel.lineBreakMode]; -#pragma clang diagnostic pop - } - - - - CGFloat titleY = KoaPullToRefreshViewHeight - KoaPullToRefreshViewHeightShowed - titleSize.height - KoaPullToRefreshViewTitleBottomMargin; - - [self.titleLabel setFrame:CGRectIntegral(CGRectMake(0, titleY, self.frame.size.width, titleSize.height))]; - - //Set state of loader label - switch (self.state) { - case KoaPullToRefreshStateStopped: - [self.loaderLabel setAlpha:0]; - [self.loaderLabel setFrame:CGRectMake(self.frame.size.width/2 - self.loaderLabel.frame.size.width/2, - titleY - 100, - self.loaderLabel.frame.size.width, - self.loaderLabel.frame.size.height)]; - break; - case KoaPullToRefreshStateTriggered: - [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionCurveEaseInOut animations:^{ - [self.loaderLabel setAlpha:1]; - [self.loaderLabel setFrame:CGRectMake(self.frame.size.width/2 - self.loaderLabel.frame.size.width/2, - titleY - 24, - self.loaderLabel.frame.size.width, - self.loaderLabel.frame.size.height)]; - } completion:NULL]; - break; - } -} - -#pragma mark - Scroll View - -- (void)resetScrollViewContentInset { - UIEdgeInsets currentInsets = self.scrollView.contentInset; - currentInsets.top = self.originalTopInset; - [self setScrollViewContentInset:currentInsets]; -} - -- (void)setScrollViewContentInsetForLoading { - UIEdgeInsets currentInsets = self.scrollView.contentInset; - //CGFloat offset = MAX(self.scrollView.contentOffset.y * -1, 0); - //currentInsets.top = MIN(offset, self.originalTopInset + self.bounds.size.height); - currentInsets.top = self.originalTopInset + self.bounds.size.height; - [self setScrollViewContentInset:currentInsets]; -} - -- (void)setScrollViewContentInset:(UIEdgeInsets)contentInset { - [UIView animateWithDuration:0.3 - delay:0 - options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState - animations:^{ - self.scrollView.contentInset = contentInset; - } - completion:NULL]; -} - -#pragma mark - Observing - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - if([keyPath isEqualToString:@"contentOffset"]) - [self scrollViewDidScroll:[[change valueForKey:NSKeyValueChangeNewKey] CGPointValue]]; - else if([keyPath isEqualToString:@"contentSize"]) { - [self layoutSubviews]; - - CGFloat yOrigin; - yOrigin = -KoaPullToRefreshViewHeight; - self.frame = CGRectMake(0, yOrigin, self.bounds.size.width, KoaPullToRefreshViewHeight); - } - else if([keyPath isEqualToString:@"frame"]) - [self layoutSubviews]; -} - -- (void)scrollViewDidScroll:(CGPoint)contentOffset { - - //Change title label alpha - [self.titleLabel setAlpha: ((contentOffset.y * -1) / KoaPullToRefreshViewHeight) - 0.1]; - - if(self.state != KoaPullToRefreshStateLoading) { - CGFloat scrollOffsetThreshold; - scrollOffsetThreshold = self.frame.origin.y-self.originalTopInset; - - if(!self.scrollView.isDragging && self.state == KoaPullToRefreshStateTriggered) - self.state = KoaPullToRefreshStateLoading; - else if(contentOffset.y < scrollOffsetThreshold && self.scrollView.isDragging && self.state == KoaPullToRefreshStateStopped) - self.state = KoaPullToRefreshStateTriggered; - else if(contentOffset.y >= scrollOffsetThreshold && self.state != KoaPullToRefreshStateStopped) - self.state = KoaPullToRefreshStateStopped; - } else { - CGFloat offset; - UIEdgeInsets contentInset; - offset = MAX(self.scrollView.contentOffset.y * -1, 0.0f); - offset = MIN(offset, self.originalTopInset + self.bounds.size.height); - contentInset = self.scrollView.contentInset; - self.scrollView.contentInset = UIEdgeInsetsMake(offset, contentInset.left, contentInset.bottom, contentInset.right); - } - - //Set content offset for special cases - if(self.state != KoaPullToRefreshStateLoading) { - if (self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed && self.scrollView.contentOffset.y < 0) { - [self.scrollView setContentInset:UIEdgeInsetsMake(abs(self.scrollView.contentOffset.y), self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right)]; - }else if(self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed) { - [self.scrollView setContentInset:UIEdgeInsetsZero]; - }else{ - [self.scrollView setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed, self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right)]; - } - } -} - - -#pragma mark - Getters - -- (UILabel *)titleLabel { - if(!_titleLabel) { - _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 210, 20)]; - _titleLabel.text = NSLocalizedString(@"Pull",); - _titleLabel.font = [UIFont boldSystemFontOfSize:14]; - _titleLabel.backgroundColor = [UIColor clearColor]; - _titleLabel.textColor = textColor; - [self addSubview:_titleLabel]; - } - return _titleLabel; -} - -- (UILabel *)loaderLabel { - if(!_loaderLabel) { - _loaderLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.frame.size.width/2 - 17/2, 0, 17, 17)]; - _loaderLabel.text = [NSString fontAwesomeIconStringForIconIdentifier:self.fontAwesomeIcon]; - _loaderLabel.font = [UIFont fontWithName:kFontAwesomeFamilyName size:20]; - _loaderLabel.backgroundColor = [UIColor clearColor]; - _loaderLabel.textColor = textColor; - [_loaderLabel sizeToFit]; - [self addSubview:_loaderLabel]; - } - return _loaderLabel; -} - -- (NSString *)fontAwesomeIcon { - if (!_fontAwesomeIcon) { - _fontAwesomeIcon = @"icon-refresh"; - } - return _fontAwesomeIcon; -} - -- (UIColor *)textColor { - return self.titleLabel.textColor; -} - -- (UIFont *)textFont { - return self.titleLabel.font; -} - -#pragma mark - Setters - -- (void)setTitle:(NSString *)title forState:(KoaPullToRefreshState)state { - if(!title) - title = @""; - - if(state == KoaPullToRefreshStateAll) - [self.titles replaceObjectsInRange:NSMakeRange(0, 3) withObjectsFromArray:@[title, title, title]]; - else - [self.titles replaceObjectAtIndex:state withObject:title]; - - [self setNeedsLayout]; -} - -- (void)setTextColor:(UIColor *)newTextColor { - textColor = newTextColor; - self.titleLabel.textColor = newTextColor; - self.loaderLabel.textColor = newTextColor; -} - -- (void)setTextFont:(UIFont *)font -{ - [self.titleLabel setFont:font]; -} - -- (void)setFontAwesomeIcon:(NSString *)fontAwesomeIcon -{ - _fontAwesomeIcon = fontAwesomeIcon; - _loaderLabel.text = [NSString fontAwesomeIconStringForIconIdentifier:self.fontAwesomeIcon]; -} - -#pragma mark - - -- (void)startAnimating{ - - //Show loader - self.state = KoaPullToRefreshStateTriggered; - [self layoutSubviews]; - - if(fequalzero(self.scrollView.contentOffset.y)) { - [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.frame.size.height) animated:YES]; - self.wasTriggeredByUser = NO; - } - else - self.wasTriggeredByUser = YES; - - self.state = KoaPullToRefreshStateLoading; -} - -- (void)stopAnimating { - self.state = KoaPullToRefreshStateStopped; - - if(!self.wasTriggeredByUser && self.scrollView.contentOffset.y < -self.originalTopInset) - [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.originalTopInset) animated:YES]; -} - -- (void)setState:(KoaPullToRefreshState)newState { - - if(_state == newState) - return; - - KoaPullToRefreshState previousState = _state; - _state = newState; - - [self setNeedsLayout]; - - switch (newState) { - case KoaPullToRefreshStateStopped: - [self stopRotatingIcon]; - [self resetScrollViewContentInset]; - self.wasTriggeredByUser = YES; - break; - - case KoaPullToRefreshStateTriggered: - break; - - case KoaPullToRefreshStateLoading: - [self startRotatingIcon]; - [self setScrollViewContentInsetForLoading]; - - if(previousState == KoaPullToRefreshStateTriggered && pullToRefreshActionHandler) - pullToRefreshActionHandler(); - - break; - } -} - -- (void)startRotatingIcon { - CABasicAnimation *rotation; - rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; - rotation.fromValue = [NSNumber numberWithFloat:0]; - rotation.toValue = [NSNumber numberWithFloat:(2*M_PI)]; - rotation.duration = 1.2; - rotation.repeatCount = HUGE_VALF; - [self.loaderLabel.layer addAnimation:rotation forKey:@"Spin"]; -} - -- (void)stopRotatingIcon { - [self.loaderLabel.layer removeAnimationForKey:@"Spin"]; -} - -@end diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index 2bfbbc8..bd39537 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -49,7 +49,7 @@ - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler { } - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler - withBackgroundColor:(UIColor *)customBackgroundColor { + withBackgroundColor:(UIColor *)customBackgroundColor { [self addPullToRefreshWithActionHandler:actionHandler withBackgroundColor:customBackgroundColor withPullToRefreshHeightShowed:KoaPullToRefreshViewHeightShowed]; } @@ -154,9 +154,9 @@ - (id)initWithFrame:(CGRect)frame { [self.loaderLabel setTextAlignment:NSTextAlignmentLeft]; self.titles = [NSMutableArray arrayWithObjects: NSLocalizedString(@"Pull",), - NSLocalizedString(@"Release",), - NSLocalizedString(@"Loading",), - nil]; + NSLocalizedString(@"Release",), + NSLocalizedString(@"Loading",), + nil]; self.wasTriggeredByUser = YES; } @@ -188,21 +188,33 @@ - (void)layoutSubviews self.titleLabel.text = [self.titles objectAtIndex:self.state]; //Set title frame - CGSize titleSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) lineBreakMode:self.titleLabel.lineBreakMode]; + + CGSize titleSize; + if ([self.titleLabel.text respondsToSelector:@selector(sizeWithAttributes:)]) { + titleSize = [self.titleLabel.text boundingRectWithSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: self.titleLabel.font} context:nil].size; + } else { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + titleSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) lineBreakMode:self.titleLabel.lineBreakMode]; +#pragma clang diagnostic pop + } + + + CGFloat titleY = KoaPullToRefreshViewHeight - KoaPullToRefreshViewHeightShowed - titleSize.height - KoaPullToRefreshViewTitleBottomMargin; [self.titleLabel setFrame:CGRectIntegral(CGRectMake(0, titleY, self.frame.size.width, titleSize.height))]; //Set state of loader label switch (self.state) { - case KoaPullToRefreshStateStopped: + case KoaPullToRefreshStateStopped: [self.loaderLabel setAlpha:0]; [self.loaderLabel setFrame:CGRectMake(self.frame.size.width/2 - self.loaderLabel.frame.size.width/2, titleY - 100, self.loaderLabel.frame.size.width, self.loaderLabel.frame.size.height)]; break; - case KoaPullToRefreshStateTriggered: + case KoaPullToRefreshStateTriggered: [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionCurveEaseInOut animations:^{ [self.loaderLabel setAlpha:1]; [self.loaderLabel setFrame:CGRectMake(self.frame.size.width/2 - self.loaderLabel.frame.size.width/2, @@ -244,7 +256,7 @@ - (void)setScrollViewContentInset:(UIEdgeInsets)contentInset { - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if([keyPath isEqualToString:@"contentOffset"]) - [self scrollViewDidScroll:[[change valueForKey:NSKeyValueChangeNewKey] CGPointValue]]; + [self scrollViewDidScroll:[[change valueForKey:NSKeyValueChangeNewKey] CGPointValue]]; else if([keyPath isEqualToString:@"contentSize"]) { [self layoutSubviews]; @@ -253,7 +265,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N self.frame = CGRectMake(0, yOrigin, self.bounds.size.width, KoaPullToRefreshViewHeight); } else if([keyPath isEqualToString:@"frame"]) - [self layoutSubviews]; + [self layoutSubviews]; } - (void)scrollViewDidScroll:(CGPoint)contentOffset { @@ -266,11 +278,11 @@ - (void)scrollViewDidScroll:(CGPoint)contentOffset { scrollOffsetThreshold = self.frame.origin.y-self.originalTopInset; if(!self.scrollView.isDragging && self.state == KoaPullToRefreshStateTriggered) - self.state = KoaPullToRefreshStateLoading; + self.state = KoaPullToRefreshStateLoading; else if(contentOffset.y < scrollOffsetThreshold && self.scrollView.isDragging && self.state == KoaPullToRefreshStateStopped) - self.state = KoaPullToRefreshStateTriggered; + self.state = KoaPullToRefreshStateTriggered; else if(contentOffset.y >= scrollOffsetThreshold && self.state != KoaPullToRefreshStateStopped) - self.state = KoaPullToRefreshStateStopped; + self.state = KoaPullToRefreshStateStopped; } else { CGFloat offset; UIEdgeInsets contentInset; @@ -339,12 +351,12 @@ - (UIFont *)textFont { - (void)setTitle:(NSString *)title forState:(KoaPullToRefreshState)state { if(!title) - title = @""; + title = @""; if(state == KoaPullToRefreshStateAll) - [self.titles replaceObjectsInRange:NSMakeRange(0, 3) withObjectsFromArray:@[title, title, title]]; + [self.titles replaceObjectsInRange:NSMakeRange(0, 3) withObjectsFromArray:@[title, title, title]]; else - [self.titles replaceObjectAtIndex:state withObject:title]; + [self.titles replaceObjectAtIndex:state withObject:title]; [self setNeedsLayout]; } @@ -379,22 +391,22 @@ - (void)startAnimating{ self.wasTriggeredByUser = NO; } else - self.wasTriggeredByUser = YES; - + self.wasTriggeredByUser = YES; + self.state = KoaPullToRefreshStateLoading; } - (void)stopAnimating { self.state = KoaPullToRefreshStateStopped; - + if(!self.wasTriggeredByUser && self.scrollView.contentOffset.y < -self.originalTopInset) - [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.originalTopInset) animated:YES]; + [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.originalTopInset) animated:YES]; } - (void)setState:(KoaPullToRefreshState)newState { if(_state == newState) - return; + return; KoaPullToRefreshState previousState = _state; _state = newState; @@ -402,21 +414,21 @@ - (void)setState:(KoaPullToRefreshState)newState { [self setNeedsLayout]; switch (newState) { - case KoaPullToRefreshStateStopped: + case KoaPullToRefreshStateStopped: [self stopRotatingIcon]; [self resetScrollViewContentInset]; self.wasTriggeredByUser = YES; break; - case KoaPullToRefreshStateTriggered: + case KoaPullToRefreshStateTriggered: break; - case KoaPullToRefreshStateLoading: + case KoaPullToRefreshStateLoading: [self startRotatingIcon]; [self setScrollViewContentInsetForLoading]; if(previousState == KoaPullToRefreshStateTriggered && pullToRefreshActionHandler) - pullToRefreshActionHandler(); + pullToRefreshActionHandler(); break; } From c8156677aada69eb2d9ad54d0ad6ac3db22fd4ac Mon Sep 17 00:00:00 2001 From: Toni Moeckel Date: Tue, 18 Feb 2014 15:17:24 +0100 Subject: [PATCH 03/21] Inset fix for iOS 7 --- KoaPullToRefresh/KoaPullToRefresh.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index bd39537..b2a337b 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -61,7 +61,7 @@ - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler KoaPullToRefreshViewHeightShowed = pullToRefreshHeightShowed; KoaPullToRefreshViewTitleBottomMargin += pullToRefreshHeightShowed; - [self setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed, self.contentInset.left, self.contentInset.bottom, self.contentInset.right)]; + [self setContentInset:UIEdgeInsetsMake(self.contentInset.top + KoaPullToRefreshViewHeightShowed, self.contentInset.left, self.contentInset.bottom, self.contentInset.right)]; if (!self.pullToRefreshView) { From e13feecb95b6b5a55c4d299acb205814576527a6 Mon Sep 17 00:00:00 2001 From: Toni Moeckel Date: Tue, 18 Feb 2014 16:22:21 +0100 Subject: [PATCH 04/21] Fix for iOS7 Problem --- KoaPullToRefresh/KoaPullToRefresh.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index b2a337b..ee385f7 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -292,6 +292,7 @@ - (void)scrollViewDidScroll:(CGPoint)contentOffset { self.scrollView.contentInset = UIEdgeInsetsMake(offset, contentInset.left, contentInset.bottom, contentInset.right); } + /* //Set content offset for special cases if(self.state != KoaPullToRefreshStateLoading) { if (self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed && self.scrollView.contentOffset.y < 0) { @@ -302,6 +303,7 @@ - (void)scrollViewDidScroll:(CGPoint)contentOffset { [self.scrollView setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed, self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right)]; } } + */ } From 60df585c7e42b899e36c3c04087ee23e2777fa4a Mon Sep 17 00:00:00 2001 From: Toni Moeckel Date: Tue, 18 Feb 2014 16:25:21 +0100 Subject: [PATCH 05/21] Updated icon for current fontawesomeIcon --- KoaPullToRefresh/KoaPullToRefresh.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index ee385f7..d844b34 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -336,7 +336,7 @@ - (UILabel *)loaderLabel { - (NSString *)fontAwesomeIcon { if (!_fontAwesomeIcon) { - _fontAwesomeIcon = @"icon-refresh"; + _fontAwesomeIcon = @"fa-refresh"; } return _fontAwesomeIcon; } From 8441462ac04b39cdc46e80fb13156eb119c16e31 Mon Sep 17 00:00:00 2001 From: Sergi Gracia Date: Tue, 4 Mar 2014 10:31:15 +0100 Subject: [PATCH 06/21] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 87bed66..3bb4ae5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +Not maintained, sorry. KoaPullToRefresh [![Build Status](https://travis-ci.org/sergigracia/KoaPullToRefresh.png)](https://travis-ci.org/sergigracia/KoaPullToRefresh) ================ KoaPullToRefresh is a minimal & easily customizable pull-to-refresh control. You can change the font, colors, size and even replace the spinning icon using FontAwesome. This library is very easy to add and customize. This pull to refresh control is developed for [Teambox](http://teambox.com) and is based on the [SVPullToRefresh](https://github.com/samvermette/SVPullToRefresh) and use [ios-fontawesome](https://github.com/alexdrone/ios-fontawesome) to work with font awesome icons. From 05bcaddedaf584b521fe3de3487b436423219c52 Mon Sep 17 00:00:00 2001 From: Sergi Gracia Date: Tue, 4 Mar 2014 10:31:38 +0100 Subject: [PATCH 07/21] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3bb4ae5..76fc783 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Not maintained, sorry. +[Not maintained.] KoaPullToRefresh [![Build Status](https://travis-ci.org/sergigracia/KoaPullToRefresh.png)](https://travis-ci.org/sergigracia/KoaPullToRefresh) ================ KoaPullToRefresh is a minimal & easily customizable pull-to-refresh control. You can change the font, colors, size and even replace the spinning icon using FontAwesome. This library is very easy to add and customize. This pull to refresh control is developed for [Teambox](http://teambox.com) and is based on the [SVPullToRefresh](https://github.com/samvermette/SVPullToRefresh) and use [ios-fontawesome](https://github.com/alexdrone/ios-fontawesome) to work with font awesome icons. From b7c5c52213dbeb97ccd7a35d6e5cc314a0cb6bc9 Mon Sep 17 00:00:00 2001 From: Max Kuznetsov Date: Wed, 16 Jul 2014 16:48:48 +0300 Subject: [PATCH 08/21] Update KoaPullToRefresh.podspec --- KoaPullToRefresh.podspec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/KoaPullToRefresh.podspec b/KoaPullToRefresh.podspec index e2819c3..c11d71f 100644 --- a/KoaPullToRefresh.podspec +++ b/KoaPullToRefresh.podspec @@ -1,5 +1,5 @@ Pod::Spec.new do |s| - s.name = 'KoaPullToRefresh' + s.name = 'SMKoaPullToRefresh' s.version = '1.0.6' s.platform = :ios, '5.0' s.license = 'MIT' @@ -7,7 +7,7 @@ Pod::Spec.new do |s| s.homepage = 'https://github.com/sergigracia/KoaPullToRefresh' s.author = { 'Sergi Gracia' => 'sergigram@gmail.com', 'Polina Flegontovna' => 'polina.flegontovna@gmail.com' } - s.source = { :git => 'https://github.com/sergigracia/KoaPullToRefresh.git', :tag => s.version.to_s } + s.source = { :git => 'https://github.com/SMCorporation/KoaPullToRefresh.git', :tag => s.version.to_s } s.description = 'Add this custom, flat, minimal, modern pull-to-refresh ' \ 'control to your app. You can change the font, colors, size ' \ @@ -23,4 +23,4 @@ Pod::Spec.new do |s| s.preserve_paths = 'Demo' s.requires_arc = true -end \ No newline at end of file +end From 3189445707f4f7e7a7ac378d07ed686a0e26c244 Mon Sep 17 00:00:00 2001 From: Max Kuznetsov Date: Wed, 16 Jul 2014 17:04:41 +0300 Subject: [PATCH 09/21] add setting refresh view height --- KoaPullToRefresh.podspec | 26 ----------------------- KoaPullToRefresh/KoaPullToRefresh.h | 19 +++++++++++++++-- KoaPullToRefresh/KoaPullToRefresh.m | 32 +++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 36 deletions(-) delete mode 100644 KoaPullToRefresh.podspec diff --git a/KoaPullToRefresh.podspec b/KoaPullToRefresh.podspec deleted file mode 100644 index c11d71f..0000000 --- a/KoaPullToRefresh.podspec +++ /dev/null @@ -1,26 +0,0 @@ -Pod::Spec.new do |s| - s.name = 'SMKoaPullToRefresh' - s.version = '1.0.6' - s.platform = :ios, '5.0' - s.license = 'MIT' - s.summary = 'Minimal & easily customizable pull-to-refresh control.' - s.homepage = 'https://github.com/sergigracia/KoaPullToRefresh' - - s.author = { 'Sergi Gracia' => 'sergigram@gmail.com', 'Polina Flegontovna' => 'polina.flegontovna@gmail.com' } - s.source = { :git => 'https://github.com/SMCorporation/KoaPullToRefresh.git', :tag => s.version.to_s } - - s.description = 'Add this custom, flat, minimal, modern pull-to-refresh ' \ - 'control to your app. You can change the font, colors, size ' \ - 'and even replace the spinning icon using FontAwesome. ' \ - 'This library is very easy to add and customize. ' \ - 'Enjoy.' - - s.frameworks = 'QuartzCore' - - s.source_files = 'KoaPullToRefresh/*.{h,m}' - s.public_header_files = 'KoaPullToRefresh/*.h' - s.dependency 'FontAwesome+iOS' - - s.preserve_paths = 'Demo' - s.requires_arc = true -end diff --git a/KoaPullToRefresh/KoaPullToRefresh.h b/KoaPullToRefresh/KoaPullToRefresh.h index dd1dae8..b434512 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.h +++ b/KoaPullToRefresh/KoaPullToRefresh.h @@ -16,8 +16,23 @@ @interface UIScrollView (KoaPullToRefresh) - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler; -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler withBackgroundColor:(UIColor *)customBackgroundColor; -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler withBackgroundColor:(UIColor *)customBackgroundColor withPullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed; +- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler + backgroundColor:(UIColor *)customBackgroundColor; + +- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler + backgroundColor:(UIColor *)customBackgroundColor + pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed; + +- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler + backgroundColor:(UIColor *)customBackgroundColor + pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed; + +- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler + backgroundColor:(UIColor *)customBackgroundColor + pullToRefreshHeight:(CGFloat)pullToRefreshHeight + pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed; + + @property (nonatomic, strong) KoaPullToRefreshView *pullToRefreshView; @property (nonatomic, assign) BOOL showsPullToRefresh; diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index 2bfbbc8..d4482df 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -44,20 +44,36 @@ - (void)setScrollViewContentInset:(UIEdgeInsets)insets; @implementation UIScrollView (KoaPullToRefresh) @dynamic pullToRefreshView, showsPullToRefresh; -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler { - [self addPullToRefreshWithActionHandler:actionHandler withBackgroundColor:[UIColor grayColor]]; + +- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler +{ + [self addPullToRefreshWithActionHandler:actionHandler backgroundColor:[UIColor grayColor]]; } - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler - withBackgroundColor:(UIColor *)customBackgroundColor { - [self addPullToRefreshWithActionHandler:actionHandler withBackgroundColor:customBackgroundColor withPullToRefreshHeightShowed:KoaPullToRefreshViewHeightShowed]; + backgroundColor:(UIColor *)customBackgroundColor +{ + [self addPullToRefreshWithActionHandler:actionHandler + backgroundColor:customBackgroundColor + pullToRefreshHeightShowed:KoaPullToRefreshViewHeightShowed]; } - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler - withBackgroundColor:(UIColor *)customBackgroundColor - withPullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed { - - //KoaPullToRefreshViewHeight = pullToRefreshHeight; + backgroundColor:(UIColor *)customBackgroundColor + pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed +{ + [self addPullToRefreshWithActionHandler:actionHandler + backgroundColor:customBackgroundColor + pullToRefreshHeight:KoaPullToRefreshViewHeight + pullToRefreshHeightShowed:KoaPullToRefreshViewHeightShowed]; +} + +- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler + backgroundColor:(UIColor *)customBackgroundColor + pullToRefreshHeight:(CGFloat)pullToRefreshHeight + pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed +{ + KoaPullToRefreshViewHeight = pullToRefreshHeight; KoaPullToRefreshViewHeightShowed = pullToRefreshHeightShowed; KoaPullToRefreshViewTitleBottomMargin += pullToRefreshHeightShowed; From ae6f6babcc2edda44f4e429a3ee878ac828abecb Mon Sep 17 00:00:00 2001 From: Max Kuznetsov Date: Fri, 18 Jul 2014 14:25:04 +0300 Subject: [PATCH 10/21] add programmatically offsetY for startAnimationg --- .../project.pbxproj | 12 +- Demo/KoaPullToRefresh/KoaPullToRefresh.h | 52 --- Demo/KoaPullToRefresh/KoaPullToRefresh.m | 439 ------------------ Demo/KoaPullToRefresh/ViewController.m | 2 +- KoaPullToRefresh/KoaPullToRefresh.h | 5 + KoaPullToRefresh/KoaPullToRefresh.m | 19 +- 6 files changed, 29 insertions(+), 500 deletions(-) delete mode 100644 Demo/KoaPullToRefresh/KoaPullToRefresh.h delete mode 100644 Demo/KoaPullToRefresh/KoaPullToRefresh.m diff --git a/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj b/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj index 3b7504b..9eb88cf 100644 --- a/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj +++ b/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 2D53FBCF197915F600BB8A19 /* KoaPullToRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D53FBCE197915F600BB8A19 /* KoaPullToRefresh.m */; }; 555AC06B173B93B0001EAC94 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 555AC06A173B93B0001EAC94 /* UIKit.framework */; }; 555AC06D173B93B0001EAC94 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 555AC06C173B93B0001EAC94 /* Foundation.framework */; }; 555AC06F173B93B0001EAC94 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 555AC06E173B93B0001EAC94 /* CoreGraphics.framework */; }; @@ -18,7 +19,6 @@ 555AC081173B93B0001EAC94 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 555AC080173B93B0001EAC94 /* Default-568h@2x.png */; }; 555AC084173B93B0001EAC94 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 555AC083173B93B0001EAC94 /* ViewController.m */; }; 555AC087173B93B0001EAC94 /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 555AC085173B93B0001EAC94 /* ViewController.xib */; }; - 555AC08F173B9DFE001EAC94 /* KoaPullToRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 555AC08E173B9DFE001EAC94 /* KoaPullToRefresh.m */; }; 555AC091173BABE7001EAC94 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 555AC090173BABE7001EAC94 /* QuartzCore.framework */; }; 555AC095173BB30D001EAC94 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 555AC092173BB30D001EAC94 /* OpenSans-Bold.ttf */; }; 555AC096173BB30D001EAC94 /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 555AC093173BB30D001EAC94 /* OpenSans-Regular.ttf */; }; @@ -29,6 +29,8 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 2D53FBCD197915F600BB8A19 /* KoaPullToRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KoaPullToRefresh.h; path = ../../KoaPullToRefresh/KoaPullToRefresh.h; sourceTree = ""; }; + 2D53FBCE197915F600BB8A19 /* KoaPullToRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KoaPullToRefresh.m; path = ../../KoaPullToRefresh/KoaPullToRefresh.m; sourceTree = ""; }; 555AC067173B93B0001EAC94 /* KoaPullToRefresh.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KoaPullToRefresh.app; sourceTree = BUILT_PRODUCTS_DIR; }; 555AC06A173B93B0001EAC94 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 555AC06C173B93B0001EAC94 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -45,8 +47,6 @@ 555AC082173B93B0001EAC94 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 555AC083173B93B0001EAC94 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 555AC086173B93B0001EAC94 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController.xib; sourceTree = ""; }; - 555AC08D173B9DFE001EAC94 /* KoaPullToRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KoaPullToRefresh.h; sourceTree = ""; }; - 555AC08E173B9DFE001EAC94 /* KoaPullToRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KoaPullToRefresh.m; sourceTree = ""; }; 555AC090173BABE7001EAC94 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 555AC092173BB30D001EAC94 /* OpenSans-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "OpenSans-Bold.ttf"; sourceTree = ""; }; 555AC093173BB30D001EAC94 /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "OpenSans-Regular.ttf"; sourceTree = ""; }; @@ -109,8 +109,8 @@ 555AC082173B93B0001EAC94 /* ViewController.h */, 555AC083173B93B0001EAC94 /* ViewController.m */, 555AC085173B93B0001EAC94 /* ViewController.xib */, - 555AC08D173B9DFE001EAC94 /* KoaPullToRefresh.h */, - 555AC08E173B9DFE001EAC94 /* KoaPullToRefresh.m */, + 2D53FBCD197915F600BB8A19 /* KoaPullToRefresh.h */, + 2D53FBCE197915F600BB8A19 /* KoaPullToRefresh.m */, 55D8EC76173D053300006E3F /* Resources */, 555AC071173B93B0001EAC94 /* Supporting Files */, ); @@ -219,7 +219,7 @@ 555AC077173B93B0001EAC94 /* main.m in Sources */, 555AC07B173B93B0001EAC94 /* AppDelegate.m in Sources */, 555AC084173B93B0001EAC94 /* ViewController.m in Sources */, - 555AC08F173B9DFE001EAC94 /* KoaPullToRefresh.m in Sources */, + 2D53FBCF197915F600BB8A19 /* KoaPullToRefresh.m in Sources */, 55D8EC7B173D053300006E3F /* UIFont+FontAwesome.m in Sources */, 55D8EC7E173D05E400006E3F /* NSString+FontAwesome.m in Sources */, ); diff --git a/Demo/KoaPullToRefresh/KoaPullToRefresh.h b/Demo/KoaPullToRefresh/KoaPullToRefresh.h deleted file mode 100644 index dd1dae8..0000000 --- a/Demo/KoaPullToRefresh/KoaPullToRefresh.h +++ /dev/null @@ -1,52 +0,0 @@ -// -// KoaPullToRefresh.h -// KoaPullToRefresh -// -// Created by Sergi Gracia on 09/05/13. -// Copyright (c) 2013 Sergi Gracia. All rights reserved. -// - -#import -#import -#import "NSString+FontAwesome.h" -#import "UIFont+FontAwesome.h" - -@class KoaPullToRefreshView; - -@interface UIScrollView (KoaPullToRefresh) - -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler; -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler withBackgroundColor:(UIColor *)customBackgroundColor; -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler withBackgroundColor:(UIColor *)customBackgroundColor withPullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed; - -@property (nonatomic, strong) KoaPullToRefreshView *pullToRefreshView; -@property (nonatomic, assign) BOOL showsPullToRefresh; - -@end - -enum { - KoaPullToRefreshStateStopped = 0, - KoaPullToRefreshStateTriggered, - KoaPullToRefreshStateLoading, - KoaPullToRefreshStateAll = 10 -}; - -typedef NSUInteger KoaPullToRefreshState; - - -@interface KoaPullToRefreshView : UIView - -@property (nonatomic, strong) UIColor *arrowColor; -@property (nonatomic, strong) UIColor *textColor; -@property (nonatomic, strong) UIFont *textFont; -@property (nonatomic, strong, readonly) UILabel *titleLabel; -@property (nonatomic, strong, readonly) UILabel *loaderLabel; -@property (nonatomic, strong, readonly) NSString *fontAwesomeIcon; -@property (nonatomic, readonly) KoaPullToRefreshState state; - -- (void)setTitle:(NSString *)title forState:(KoaPullToRefreshState)state; -- (void)setFontAwesomeIcon:(NSString *)fontAwesomeIcon; -- (void)startAnimating; -- (void)stopAnimating; - -@end diff --git a/Demo/KoaPullToRefresh/KoaPullToRefresh.m b/Demo/KoaPullToRefresh/KoaPullToRefresh.m deleted file mode 100644 index 2bfbbc8..0000000 --- a/Demo/KoaPullToRefresh/KoaPullToRefresh.m +++ /dev/null @@ -1,439 +0,0 @@ -// -// KoaPullToRefresh.m -// KoaPullToRefresh -// -// Created by Sergi Gracia on 09/05/13. -// Copyright (c) 2013 Sergi Gracia. All rights reserved. -// - -#import "KoaPullToRefresh.h" -#import - -#define fequal(a,b) (fabs((a) - (b)) < FLT_EPSILON) -#define fequalzero(a) (fabs(a) < FLT_EPSILON) - -static CGFloat KoaPullToRefreshViewHeight = 82; -static CGFloat KoaPullToRefreshViewHeightShowed = 0; -static CGFloat KoaPullToRefreshViewTitleBottomMargin = 12; - -@interface KoaPullToRefreshView () - -@property (nonatomic, copy) void (^pullToRefreshActionHandler)(void); -@property (nonatomic, strong, readwrite) UILabel *titleLabel; -@property (nonatomic, strong, readwrite) UILabel *loaderLabel; -@property (nonatomic, readwrite) KoaPullToRefreshState state; -@property (nonatomic, strong) NSMutableArray *titles; -@property (nonatomic, weak) UIScrollView *scrollView; -@property (nonatomic, readwrite) CGFloat originalTopInset; -@property (nonatomic, readwrite) CGFloat originalBottomInset; -@property (nonatomic, assign) BOOL wasTriggeredByUser; -@property (nonatomic, assign) BOOL showsPullToRefresh; -@property(nonatomic, assign) BOOL isObserving; - -- (void)resetScrollViewContentInset; -- (void)setScrollViewContentInsetForLoading; -- (void)setScrollViewContentInset:(UIEdgeInsets)insets; - -@end - -#pragma mark - UIScrollView (KoaPullToRefresh) -#import - -static char UIScrollViewPullToRefreshView; - -@implementation UIScrollView (KoaPullToRefresh) -@dynamic pullToRefreshView, showsPullToRefresh; - -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler { - [self addPullToRefreshWithActionHandler:actionHandler withBackgroundColor:[UIColor grayColor]]; -} - -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler - withBackgroundColor:(UIColor *)customBackgroundColor { - [self addPullToRefreshWithActionHandler:actionHandler withBackgroundColor:customBackgroundColor withPullToRefreshHeightShowed:KoaPullToRefreshViewHeightShowed]; -} - -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler - withBackgroundColor:(UIColor *)customBackgroundColor - withPullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed { - - //KoaPullToRefreshViewHeight = pullToRefreshHeight; - KoaPullToRefreshViewHeightShowed = pullToRefreshHeightShowed; - KoaPullToRefreshViewTitleBottomMargin += pullToRefreshHeightShowed; - - [self setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed, self.contentInset.left, self.contentInset.bottom, self.contentInset.right)]; - - if (!self.pullToRefreshView) { - - //Initial y position - CGFloat yOrigin = -KoaPullToRefreshViewHeight; - - //Put background extra to fill top white space - UIView *backgroundExtra = [[UIView alloc] initWithFrame:CGRectMake(0, -KoaPullToRefreshViewHeight*8, self.bounds.size.width, KoaPullToRefreshViewHeight*8)]; - [backgroundExtra setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; - [backgroundExtra setBackgroundColor:customBackgroundColor]; - [self addSubview:backgroundExtra]; - - //Init pull to refresh view - KoaPullToRefreshView *view = [[KoaPullToRefreshView alloc] initWithFrame:CGRectMake(0, yOrigin, self.bounds.size.width, KoaPullToRefreshViewHeight + KoaPullToRefreshViewHeightShowed)]; - view.pullToRefreshActionHandler = actionHandler; - view.scrollView = self; - view.backgroundColor = customBackgroundColor; - [self addSubview:view]; - - view.originalTopInset = self.contentInset.top; - view.originalBottomInset = self.contentInset.bottom; - - self.pullToRefreshView = view; - self.showsPullToRefresh = YES; - } -} - -- (void)setPullToRefreshView:(KoaPullToRefreshView *)pullToRefreshView { - [self willChangeValueForKey:@"KoaPullToRefreshView"]; - objc_setAssociatedObject(self, &UIScrollViewPullToRefreshView, - pullToRefreshView, - OBJC_ASSOCIATION_ASSIGN); - [self didChangeValueForKey:@"KoaPullToRefreshView"]; -} - -- (KoaPullToRefreshView *)pullToRefreshView { - return objc_getAssociatedObject(self, &UIScrollViewPullToRefreshView); -} - -- (void)setShowsPullToRefresh:(BOOL)showsPullToRefresh { - self.pullToRefreshView.hidden = !showsPullToRefresh; - - if(!showsPullToRefresh) { - if (self.pullToRefreshView.isObserving) { - [self removeObserver:self.pullToRefreshView forKeyPath:@"contentOffset"]; - [self removeObserver:self.pullToRefreshView forKeyPath:@"frame"]; - [self.pullToRefreshView resetScrollViewContentInset]; - self.pullToRefreshView.isObserving = NO; - } - }else { - if (!self.pullToRefreshView.isObserving) { - [self addObserver:self.pullToRefreshView forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil]; - [self addObserver:self.pullToRefreshView forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil]; - [self addObserver:self.pullToRefreshView forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil]; - self.pullToRefreshView.isObserving = YES; - - CGFloat yOrigin = -KoaPullToRefreshViewHeight; - self.pullToRefreshView.frame = CGRectMake(0, yOrigin, self.bounds.size.width, KoaPullToRefreshViewHeight + KoaPullToRefreshViewHeightShowed); - } - } -} - -- (BOOL)showsPullToRefresh { - return !self.pullToRefreshView.hidden; -} - -@end - - -#pragma mark - KoaPullToRefresh -@implementation KoaPullToRefreshView - -@synthesize pullToRefreshActionHandler, arrowColor, textColor, textFont; -@synthesize state = _state; -@synthesize scrollView = _scrollView; -@synthesize showsPullToRefresh = _showsPullToRefresh; -@synthesize titleLabel = _titleLabel; -@synthesize loaderLabel = _loaderLabel; -@synthesize fontAwesomeIcon = _fontAwesomeIcon; - -- (id)initWithFrame:(CGRect)frame { - if(self = [super initWithFrame:frame]) { - - // default styling values - self.textColor = [UIColor darkGrayColor]; - self.backgroundColor = [UIColor whiteColor]; - self.autoresizingMask = UIViewAutoresizingFlexibleWidth; - self.state = KoaPullToRefreshStateStopped; - [self.titleLabel setTextAlignment:NSTextAlignmentCenter]; - [self.loaderLabel setTextAlignment:NSTextAlignmentLeft]; - - self.titles = [NSMutableArray arrayWithObjects: NSLocalizedString(@"Pull",), - NSLocalizedString(@"Release",), - NSLocalizedString(@"Loading",), - nil]; - - self.wasTriggeredByUser = YES; - } - return self; -} - -- (void)willMoveToSuperview:(UIView *)newSuperview { - if (self.superview && newSuperview == nil) { - UIScrollView *scrollView = (UIScrollView *)self.superview; - if (scrollView.showsPullToRefresh) { - if (self.isObserving) { - //If enter this branch, it is the moment just before "KoaPullToRefreshView's dealloc", so remove observer here - [scrollView removeObserver:self forKeyPath:@"contentOffset"]; - [scrollView removeObserver:self forKeyPath:@"contentSize"]; - [scrollView removeObserver:self forKeyPath:@"frame"]; - self.isObserving = NO; - } - } - } -} - -- (void)layoutSubviews -{ - CGFloat leftViewWidth = 60; - CGFloat margin = 10; - CGFloat labelMaxWidth = self.bounds.size.width - margin - leftViewWidth; - - //Set title text - self.titleLabel.text = [self.titles objectAtIndex:self.state]; - - //Set title frame - CGSize titleSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) lineBreakMode:self.titleLabel.lineBreakMode]; - CGFloat titleY = KoaPullToRefreshViewHeight - KoaPullToRefreshViewHeightShowed - titleSize.height - KoaPullToRefreshViewTitleBottomMargin; - - [self.titleLabel setFrame:CGRectIntegral(CGRectMake(0, titleY, self.frame.size.width, titleSize.height))]; - - //Set state of loader label - switch (self.state) { - case KoaPullToRefreshStateStopped: - [self.loaderLabel setAlpha:0]; - [self.loaderLabel setFrame:CGRectMake(self.frame.size.width/2 - self.loaderLabel.frame.size.width/2, - titleY - 100, - self.loaderLabel.frame.size.width, - self.loaderLabel.frame.size.height)]; - break; - case KoaPullToRefreshStateTriggered: - [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionCurveEaseInOut animations:^{ - [self.loaderLabel setAlpha:1]; - [self.loaderLabel setFrame:CGRectMake(self.frame.size.width/2 - self.loaderLabel.frame.size.width/2, - titleY - 24, - self.loaderLabel.frame.size.width, - self.loaderLabel.frame.size.height)]; - } completion:NULL]; - break; - } -} - -#pragma mark - Scroll View - -- (void)resetScrollViewContentInset { - UIEdgeInsets currentInsets = self.scrollView.contentInset; - currentInsets.top = self.originalTopInset; - [self setScrollViewContentInset:currentInsets]; -} - -- (void)setScrollViewContentInsetForLoading { - UIEdgeInsets currentInsets = self.scrollView.contentInset; - //CGFloat offset = MAX(self.scrollView.contentOffset.y * -1, 0); - //currentInsets.top = MIN(offset, self.originalTopInset + self.bounds.size.height); - currentInsets.top = self.originalTopInset + self.bounds.size.height; - [self setScrollViewContentInset:currentInsets]; -} - -- (void)setScrollViewContentInset:(UIEdgeInsets)contentInset { - [UIView animateWithDuration:0.3 - delay:0 - options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState - animations:^{ - self.scrollView.contentInset = contentInset; - } - completion:NULL]; -} - -#pragma mark - Observing - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - if([keyPath isEqualToString:@"contentOffset"]) - [self scrollViewDidScroll:[[change valueForKey:NSKeyValueChangeNewKey] CGPointValue]]; - else if([keyPath isEqualToString:@"contentSize"]) { - [self layoutSubviews]; - - CGFloat yOrigin; - yOrigin = -KoaPullToRefreshViewHeight; - self.frame = CGRectMake(0, yOrigin, self.bounds.size.width, KoaPullToRefreshViewHeight); - } - else if([keyPath isEqualToString:@"frame"]) - [self layoutSubviews]; -} - -- (void)scrollViewDidScroll:(CGPoint)contentOffset { - - //Change title label alpha - [self.titleLabel setAlpha: ((contentOffset.y * -1) / KoaPullToRefreshViewHeight) - 0.1]; - - if(self.state != KoaPullToRefreshStateLoading) { - CGFloat scrollOffsetThreshold; - scrollOffsetThreshold = self.frame.origin.y-self.originalTopInset; - - if(!self.scrollView.isDragging && self.state == KoaPullToRefreshStateTriggered) - self.state = KoaPullToRefreshStateLoading; - else if(contentOffset.y < scrollOffsetThreshold && self.scrollView.isDragging && self.state == KoaPullToRefreshStateStopped) - self.state = KoaPullToRefreshStateTriggered; - else if(contentOffset.y >= scrollOffsetThreshold && self.state != KoaPullToRefreshStateStopped) - self.state = KoaPullToRefreshStateStopped; - } else { - CGFloat offset; - UIEdgeInsets contentInset; - offset = MAX(self.scrollView.contentOffset.y * -1, 0.0f); - offset = MIN(offset, self.originalTopInset + self.bounds.size.height); - contentInset = self.scrollView.contentInset; - self.scrollView.contentInset = UIEdgeInsetsMake(offset, contentInset.left, contentInset.bottom, contentInset.right); - } - - //Set content offset for special cases - if(self.state != KoaPullToRefreshStateLoading) { - if (self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed && self.scrollView.contentOffset.y < 0) { - [self.scrollView setContentInset:UIEdgeInsetsMake(abs(self.scrollView.contentOffset.y), self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right)]; - }else if(self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed) { - [self.scrollView setContentInset:UIEdgeInsetsZero]; - }else{ - [self.scrollView setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed, self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right)]; - } - } -} - - -#pragma mark - Getters - -- (UILabel *)titleLabel { - if(!_titleLabel) { - _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 210, 20)]; - _titleLabel.text = NSLocalizedString(@"Pull",); - _titleLabel.font = [UIFont boldSystemFontOfSize:14]; - _titleLabel.backgroundColor = [UIColor clearColor]; - _titleLabel.textColor = textColor; - [self addSubview:_titleLabel]; - } - return _titleLabel; -} - -- (UILabel *)loaderLabel { - if(!_loaderLabel) { - _loaderLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.frame.size.width/2 - 17/2, 0, 17, 17)]; - _loaderLabel.text = [NSString fontAwesomeIconStringForIconIdentifier:self.fontAwesomeIcon]; - _loaderLabel.font = [UIFont fontWithName:kFontAwesomeFamilyName size:20]; - _loaderLabel.backgroundColor = [UIColor clearColor]; - _loaderLabel.textColor = textColor; - [_loaderLabel sizeToFit]; - [self addSubview:_loaderLabel]; - } - return _loaderLabel; -} - -- (NSString *)fontAwesomeIcon { - if (!_fontAwesomeIcon) { - _fontAwesomeIcon = @"icon-refresh"; - } - return _fontAwesomeIcon; -} - -- (UIColor *)textColor { - return self.titleLabel.textColor; -} - -- (UIFont *)textFont { - return self.titleLabel.font; -} - -#pragma mark - Setters - -- (void)setTitle:(NSString *)title forState:(KoaPullToRefreshState)state { - if(!title) - title = @""; - - if(state == KoaPullToRefreshStateAll) - [self.titles replaceObjectsInRange:NSMakeRange(0, 3) withObjectsFromArray:@[title, title, title]]; - else - [self.titles replaceObjectAtIndex:state withObject:title]; - - [self setNeedsLayout]; -} - -- (void)setTextColor:(UIColor *)newTextColor { - textColor = newTextColor; - self.titleLabel.textColor = newTextColor; - self.loaderLabel.textColor = newTextColor; -} - -- (void)setTextFont:(UIFont *)font -{ - [self.titleLabel setFont:font]; -} - -- (void)setFontAwesomeIcon:(NSString *)fontAwesomeIcon -{ - _fontAwesomeIcon = fontAwesomeIcon; - _loaderLabel.text = [NSString fontAwesomeIconStringForIconIdentifier:self.fontAwesomeIcon]; -} - -#pragma mark - - -- (void)startAnimating{ - - //Show loader - self.state = KoaPullToRefreshStateTriggered; - [self layoutSubviews]; - - if(fequalzero(self.scrollView.contentOffset.y)) { - [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.frame.size.height) animated:YES]; - self.wasTriggeredByUser = NO; - } - else - self.wasTriggeredByUser = YES; - - self.state = KoaPullToRefreshStateLoading; -} - -- (void)stopAnimating { - self.state = KoaPullToRefreshStateStopped; - - if(!self.wasTriggeredByUser && self.scrollView.contentOffset.y < -self.originalTopInset) - [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.originalTopInset) animated:YES]; -} - -- (void)setState:(KoaPullToRefreshState)newState { - - if(_state == newState) - return; - - KoaPullToRefreshState previousState = _state; - _state = newState; - - [self setNeedsLayout]; - - switch (newState) { - case KoaPullToRefreshStateStopped: - [self stopRotatingIcon]; - [self resetScrollViewContentInset]; - self.wasTriggeredByUser = YES; - break; - - case KoaPullToRefreshStateTriggered: - break; - - case KoaPullToRefreshStateLoading: - [self startRotatingIcon]; - [self setScrollViewContentInsetForLoading]; - - if(previousState == KoaPullToRefreshStateTriggered && pullToRefreshActionHandler) - pullToRefreshActionHandler(); - - break; - } -} - -- (void)startRotatingIcon { - CABasicAnimation *rotation; - rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; - rotation.fromValue = [NSNumber numberWithFloat:0]; - rotation.toValue = [NSNumber numberWithFloat:(2*M_PI)]; - rotation.duration = 1.2; - rotation.repeatCount = HUGE_VALF; - [self.loaderLabel.layer addAnimation:rotation forKey:@"Spin"]; -} - -- (void)stopRotatingIcon { - [self.loaderLabel.layer removeAnimationForKey:@"Spin"]; -} - -@end diff --git a/Demo/KoaPullToRefresh/ViewController.m b/Demo/KoaPullToRefresh/ViewController.m index dcc2122..3abc958 100644 --- a/Demo/KoaPullToRefresh/ViewController.m +++ b/Demo/KoaPullToRefresh/ViewController.m @@ -43,7 +43,7 @@ - (void)viewDidLoad //Add pull to refresh [self.tableView addPullToRefreshWithActionHandler:^{ [self refreshTable]; - } withBackgroundColor:[UIColor colorWithRed:0.251 green:0.663 blue:0.827 alpha:1] withPullToRefreshHeightShowed:4]; + } backgroundColor:[UIColor colorWithRed:0.251 green:0.663 blue:0.827 alpha:1] pullToRefreshHeightShowed:4]; //Customize pulltorefresh text colors [self.tableView.pullToRefreshView setTextColor:[UIColor whiteColor]]; diff --git a/KoaPullToRefresh/KoaPullToRefresh.h b/KoaPullToRefresh/KoaPullToRefresh.h index b434512..e909718 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.h +++ b/KoaPullToRefresh/KoaPullToRefresh.h @@ -32,6 +32,11 @@ pullToRefreshHeight:(CGFloat)pullToRefreshHeight pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed; +- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler + backgroundColor:(UIColor *)customBackgroundColor + pullToRefreshHeight:(CGFloat)pullToRefreshHeight + pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed + programmingAnimationOffestY:(CGFloat)programmingAnimationOffestY; @property (nonatomic, strong) KoaPullToRefreshView *pullToRefreshView; diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index d4482df..e77795f 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -28,7 +28,8 @@ @interface KoaPullToRefreshView () @property (nonatomic, readwrite) CGFloat originalBottomInset; @property (nonatomic, assign) BOOL wasTriggeredByUser; @property (nonatomic, assign) BOOL showsPullToRefresh; -@property(nonatomic, assign) BOOL isObserving; +@property (nonatomic, assign) BOOL isObserving; +@property (nonatomic, assign) CGFloat offsetY; - (void)resetScrollViewContentInset; - (void)setScrollViewContentInsetForLoading; @@ -73,6 +74,20 @@ - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler pullToRefreshHeight:(CGFloat)pullToRefreshHeight pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed { + [self addPullToRefreshWithActionHandler:actionHandler + backgroundColor:customBackgroundColor + pullToRefreshHeight:pullToRefreshHeight + pullToRefreshHeightShowed:pullToRefreshHeightShowed + programmingAnimationOffestY:0]; +} + +- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler + backgroundColor:(UIColor *)customBackgroundColor + pullToRefreshHeight:(CGFloat)pullToRefreshHeight + pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed + programmingAnimationOffestY:(CGFloat)programmingAnimationOffestY +{ + self.pullToRefreshView.offsetY = programmingAnimationOffestY; KoaPullToRefreshViewHeight = pullToRefreshHeight; KoaPullToRefreshViewHeightShowed = pullToRefreshHeightShowed; KoaPullToRefreshViewTitleBottomMargin += pullToRefreshHeightShowed; @@ -391,7 +406,7 @@ - (void)startAnimating{ [self layoutSubviews]; if(fequalzero(self.scrollView.contentOffset.y)) { - [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.frame.size.height) animated:YES]; + [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.offsetY) animated:YES]; self.wasTriggeredByUser = NO; } else From 85c3013469d4ec1e2e707c595da06471eb076a56 Mon Sep 17 00:00:00 2001 From: Max Kuznetsov Date: Fri, 18 Jul 2014 17:38:58 +0300 Subject: [PATCH 11/21] fix minor bugs --- KoaPullToRefresh/KoaPullToRefresh.h | 1 + KoaPullToRefresh/KoaPullToRefresh.m | 60 +++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.h b/KoaPullToRefresh/KoaPullToRefresh.h index e909718..753b2bc 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.h +++ b/KoaPullToRefresh/KoaPullToRefresh.h @@ -63,6 +63,7 @@ typedef NSUInteger KoaPullToRefreshState; @property (nonatomic, strong, readonly) UILabel *loaderLabel; @property (nonatomic, strong, readonly) NSString *fontAwesomeIcon; @property (nonatomic, readonly) KoaPullToRefreshState state; +@property (nonatomic, assign) BOOL disable; - (void)setTitle:(NSString *)title forState:(KoaPullToRefreshState)state; - (void)setFontAwesomeIcon:(NSString *)fontAwesomeIcon; diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index e77795f..9823cab 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -29,8 +29,10 @@ @interface KoaPullToRefreshView () @property (nonatomic, assign) BOOL wasTriggeredByUser; @property (nonatomic, assign) BOOL showsPullToRefresh; @property (nonatomic, assign) BOOL isObserving; +@property (nonatomic, assign) BOOL programmaticallyLoading; @property (nonatomic, assign) CGFloat offsetY; + - (void)resetScrollViewContentInset; - (void)setScrollViewContentInsetForLoading; - (void)setScrollViewContentInset:(UIEdgeInsets)insets; @@ -247,13 +249,22 @@ - (void)layoutSubviews #pragma mark - Scroll View -- (void)resetScrollViewContentInset { +- (void)resetScrollViewContentInset +{ + if (self.disable) { + return; + } + UIEdgeInsets currentInsets = self.scrollView.contentInset; currentInsets.top = self.originalTopInset; [self setScrollViewContentInset:currentInsets]; } - (void)setScrollViewContentInsetForLoading { + if (self.disable) { + return; + } + UIEdgeInsets currentInsets = self.scrollView.contentInset; //CGFloat offset = MAX(self.scrollView.contentOffset.y * -1, 0); //currentInsets.top = MIN(offset, self.originalTopInset + self.bounds.size.height); @@ -273,9 +284,20 @@ - (void)setScrollViewContentInset:(UIEdgeInsets)contentInset { #pragma mark - Observing -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - if([keyPath isEqualToString:@"contentOffset"]) +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if (self.disable) { + return; + } + + if (self.scrollView.contentOffset.y < -self.offsetY && self.programmaticallyLoading) { + self.scrollView.contentOffset = CGPointMake(0, -self.offsetY); + } + + + if([keyPath isEqualToString:@"contentOffset"]) { [self scrollViewDidScroll:[[change valueForKey:NSKeyValueChangeNewKey] CGPointValue]]; + } else if([keyPath isEqualToString:@"contentSize"]) { [self layoutSubviews]; @@ -283,11 +305,16 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N yOrigin = -KoaPullToRefreshViewHeight; self.frame = CGRectMake(0, yOrigin, self.bounds.size.width, KoaPullToRefreshViewHeight); } - else if([keyPath isEqualToString:@"frame"]) + else if([keyPath isEqualToString:@"frame"]) { [self layoutSubviews]; + } } -- (void)scrollViewDidScroll:(CGPoint)contentOffset { +- (void)scrollViewDidScroll:(CGPoint)contentOffset +{ + if (self.disable) { + return; + } //Change title label alpha [self.titleLabel setAlpha: ((contentOffset.y * -1) / KoaPullToRefreshViewHeight) - 0.1]; @@ -315,12 +342,13 @@ - (void)scrollViewDidScroll:(CGPoint)contentOffset { if(self.state != KoaPullToRefreshStateLoading) { if (self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed && self.scrollView.contentOffset.y < 0) { [self.scrollView setContentInset:UIEdgeInsetsMake(abs(self.scrollView.contentOffset.y), self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right)]; - }else if(self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed) { + } else if(self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed) { [self.scrollView setContentInset:UIEdgeInsetsZero]; - }else{ + } else { [self.scrollView setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed, self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right)]; } } + self.wasTriggeredByUser = YES; } @@ -399,18 +427,15 @@ - (void)setFontAwesomeIcon:(NSString *)fontAwesomeIcon #pragma mark - -- (void)startAnimating{ - +- (void)startAnimating +{ //Show loader + self.wasTriggeredByUser = NO; + self.programmaticallyLoading = YES; self.state = KoaPullToRefreshStateTriggered; [self layoutSubviews]; - if(fequalzero(self.scrollView.contentOffset.y)) { - [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.offsetY) animated:YES]; - self.wasTriggeredByUser = NO; - } - else - self.wasTriggeredByUser = YES; + [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.offsetY) animated:YES]; self.state = KoaPullToRefreshStateLoading; } @@ -418,8 +443,9 @@ - (void)startAnimating{ - (void)stopAnimating { self.state = KoaPullToRefreshStateStopped; - if(!self.wasTriggeredByUser && self.scrollView.contentOffset.y < -self.originalTopInset) + if(self.scrollView.contentOffset.y < -self.originalTopInset) { [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.originalTopInset) animated:YES]; + } } - (void)setState:(KoaPullToRefreshState)newState { @@ -436,6 +462,7 @@ - (void)setState:(KoaPullToRefreshState)newState { case KoaPullToRefreshStateStopped: [self stopRotatingIcon]; [self resetScrollViewContentInset]; + self.scrollView.contentOffset = CGPointZero; self.wasTriggeredByUser = YES; break; @@ -464,6 +491,7 @@ - (void)startRotatingIcon { } - (void)stopRotatingIcon { + self.programmaticallyLoading = NO; [self.loaderLabel.layer removeAnimationForKey:@"Spin"]; } From f24d1b99d9a11c26ad87fcb78a90f0596a5ab090 Mon Sep 17 00:00:00 2001 From: Max Kuznetsov Date: Tue, 22 Jul 2014 16:01:24 +0300 Subject: [PATCH 12/21] modified refresh logic --- KoaPullToRefresh/KoaPullToRefresh.m | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index 9823cab..3916177 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -80,7 +80,7 @@ - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler backgroundColor:customBackgroundColor pullToRefreshHeight:pullToRefreshHeight pullToRefreshHeightShowed:pullToRefreshHeightShowed - programmingAnimationOffestY:0]; + programmingAnimationOffestY:pullToRefreshHeight]; } - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler @@ -119,6 +119,8 @@ - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler self.pullToRefreshView = view; self.showsPullToRefresh = YES; + } else { + self.pullToRefreshView.pullToRefreshActionHandler = actionHandler; } } @@ -341,11 +343,17 @@ - (void)scrollViewDidScroll:(CGPoint)contentOffset //Set content offset for special cases if(self.state != KoaPullToRefreshStateLoading) { if (self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed && self.scrollView.contentOffset.y < 0) { - [self.scrollView setContentInset:UIEdgeInsetsMake(abs(self.scrollView.contentOffset.y), self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right)]; + [self.scrollView setContentInset:UIEdgeInsetsMake(abs(self.scrollView.contentOffset.y), + self.scrollView.contentInset.left, + self.scrollView.contentInset.bottom, + self.scrollView.contentInset.right)]; } else if(self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed) { [self.scrollView setContentInset:UIEdgeInsetsZero]; } else { - [self.scrollView setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed, self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right)]; + [self.scrollView setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed, + self.scrollView.contentInset.left, + self.scrollView.contentInset.bottom, + self.scrollView.contentInset.right)]; } } self.wasTriggeredByUser = YES; @@ -462,7 +470,6 @@ - (void)setState:(KoaPullToRefreshState)newState { case KoaPullToRefreshStateStopped: [self stopRotatingIcon]; [self resetScrollViewContentInset]; - self.scrollView.contentOffset = CGPointZero; self.wasTriggeredByUser = YES; break; From 4ac9b247461ddcc2e75695fd795581529fa6559b Mon Sep 17 00:00:00 2001 From: Max Kuznetsov Date: Wed, 23 Jul 2014 15:55:07 +0300 Subject: [PATCH 13/21] fix contentOffset after startAnimation calling --- KoaPullToRefresh/KoaPullToRefresh.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index 3916177..f88a067 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -89,7 +89,6 @@ - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed programmingAnimationOffestY:(CGFloat)programmingAnimationOffestY { - self.pullToRefreshView.offsetY = programmingAnimationOffestY; KoaPullToRefreshViewHeight = pullToRefreshHeight; KoaPullToRefreshViewHeightShowed = pullToRefreshHeightShowed; KoaPullToRefreshViewTitleBottomMargin += pullToRefreshHeightShowed; @@ -122,6 +121,8 @@ - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler } else { self.pullToRefreshView.pullToRefreshActionHandler = actionHandler; } + + self.pullToRefreshView.offsetY = programmingAnimationOffestY; } - (void)setPullToRefreshView:(KoaPullToRefreshView *)pullToRefreshView { From b4513c699d056369d24e90906142b37d38bbc9a9 Mon Sep 17 00:00:00 2001 From: Max Kuznetsov Date: Thu, 24 Jul 2014 14:44:35 +0300 Subject: [PATCH 14/21] fix bug with collection view --- KoaPullToRefresh/KoaPullToRefresh.m | 74 ++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 17 deletions(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index f88a067..7031df5 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -34,8 +34,9 @@ @interface KoaPullToRefreshView () - (void)resetScrollViewContentInset; -- (void)setScrollViewContentInsetForLoading; -- (void)setScrollViewContentInset:(UIEdgeInsets)insets; +- (void)setScrollViewContentInsetForLoadingWithComplitionBlock:(void(^)())complitionBlock; +- (void)setScrollViewContentInset:(UIEdgeInsets)contentInset withComplitionBlock:(void(^)())complitionBlock; +- (void)setScrollViewContentOffset:(CGPoint)contentOffset withComplitionBlock:(void(^)())complitionBlock; @end @@ -190,9 +191,9 @@ - (id)initWithFrame:(CGRect)frame { [self.loaderLabel setTextAlignment:NSTextAlignmentLeft]; self.titles = [NSMutableArray arrayWithObjects: NSLocalizedString(@"Pull",), - NSLocalizedString(@"Release",), - NSLocalizedString(@"Loading",), - nil]; + NSLocalizedString(@"Release",), + NSLocalizedString(@"Loading",), + nil]; self.wasTriggeredByUser = YES; } @@ -260,10 +261,19 @@ - (void)resetScrollViewContentInset UIEdgeInsets currentInsets = self.scrollView.contentInset; currentInsets.top = self.originalTopInset; - [self setScrollViewContentInset:currentInsets]; + + __weak KoaPullToRefreshView *weakSelf = self; + [self setScrollViewContentInset:currentInsets withComplitionBlock:^{ + if ([weakSelf.scrollView isKindOfClass:[UICollectionView class]]) { + if (weakSelf.scrollView.contentOffset.y < 0) { + [weakSelf.scrollView setContentOffset:CGPointZero animated:YES]; + } + } + }]; } -- (void)setScrollViewContentInsetForLoading { +- (void)setScrollViewContentInsetForLoadingWithComplitionBlock:(void(^)())complitionBlock +{ if (self.disable) { return; } @@ -272,17 +282,22 @@ - (void)setScrollViewContentInsetForLoading { //CGFloat offset = MAX(self.scrollView.contentOffset.y * -1, 0); //currentInsets.top = MIN(offset, self.originalTopInset + self.bounds.size.height); currentInsets.top = self.originalTopInset + self.bounds.size.height; - [self setScrollViewContentInset:currentInsets]; + [self setScrollViewContentInset:currentInsets withComplitionBlock:complitionBlock]; } -- (void)setScrollViewContentInset:(UIEdgeInsets)contentInset { +- (void)setScrollViewContentInset:(UIEdgeInsets)contentInset withComplitionBlock:(void(^)())complitionBlock +{ [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState animations:^{ self.scrollView.contentInset = contentInset; } - completion:NULL]; + completion:^(BOOL finished) { + if (complitionBlock) { + complitionBlock(); + } + }]; } #pragma mark - Observing @@ -292,7 +307,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N if (self.disable) { return; } - + if (self.scrollView.contentOffset.y < -self.offsetY && self.programmaticallyLoading) { self.scrollView.contentOffset = CGPointMake(0, -self.offsetY); } @@ -444,14 +459,36 @@ - (void)startAnimating self.state = KoaPullToRefreshStateTriggered; [self layoutSubviews]; - [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.offsetY) animated:YES]; + __weak KoaPullToRefreshView *weakSelf = self; + [self setScrollViewContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.offsetY) withComplitionBlock:^{ + weakSelf.state = KoaPullToRefreshStateLoading; + }]; +// [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.offsetY) animated:YES]; +// [self sets] + +} - self.state = KoaPullToRefreshStateLoading; +- (void)setScrollViewContentOffset:(CGPoint)contentOffset withComplitionBlock:(void(^)())complitionBlock +{ + __weak KoaPullToRefreshView *weakSelf = self; + [UIView animateWithDuration:0.3 + delay:0 + options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState + animations:^{ + weakSelf.scrollView.contentOffset = contentOffset; + } + completion:^(BOOL finished) { + if (complitionBlock) { + complitionBlock(); + } + }]; + } + - (void)stopAnimating { self.state = KoaPullToRefreshStateStopped; - + if(self.scrollView.contentOffset.y < -self.originalTopInset) { [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.originalTopInset) animated:YES]; } @@ -479,10 +516,13 @@ - (void)setState:(KoaPullToRefreshState)newState { case KoaPullToRefreshStateLoading: [self startRotatingIcon]; - [self setScrollViewContentInsetForLoading]; - if(previousState == KoaPullToRefreshStateTriggered && pullToRefreshActionHandler) - pullToRefreshActionHandler(); + __weak void (^actionHandler)(void) = pullToRefreshActionHandler; + [self setScrollViewContentInsetForLoadingWithComplitionBlock:^{ + if(previousState == KoaPullToRefreshStateTriggered && actionHandler) { + actionHandler(); + } + }]; break; } From e54ff8ec62f84b6a3ae6565191d6d743f745cbaf Mon Sep 17 00:00:00 2001 From: Max Kuznetsov Date: Fri, 25 Jul 2014 18:07:20 +0300 Subject: [PATCH 15/21] fix leaks with observing --- KoaPullToRefresh/KoaPullToRefresh.m | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index 7031df5..7932dc1 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -144,6 +144,7 @@ - (void)setShowsPullToRefresh:(BOOL)showsPullToRefresh { if(!showsPullToRefresh) { if (self.pullToRefreshView.isObserving) { [self removeObserver:self.pullToRefreshView forKeyPath:@"contentOffset"]; + [self removeObserver:self.pullToRefreshView forKeyPath:@"contentSize"]; [self removeObserver:self.pullToRefreshView forKeyPath:@"frame"]; [self.pullToRefreshView resetScrollViewContentInset]; self.pullToRefreshView.isObserving = NO; @@ -161,6 +162,7 @@ - (void)setShowsPullToRefresh:(BOOL)showsPullToRefresh { } } + - (BOOL)showsPullToRefresh { return !self.pullToRefreshView.hidden; } @@ -205,6 +207,11 @@ - (void)willMoveToSuperview:(UIView *)newSuperview { UIScrollView *scrollView = (UIScrollView *)self.superview; if (scrollView.showsPullToRefresh) { if (self.isObserving) { + if (self.state == KoaPullToRefreshStateLoading) { + self.state = KoaPullToRefreshStateStopped; + [self stopAnimating]; + } + //If enter this branch, it is the moment just before "KoaPullToRefreshView's dealloc", so remove observer here [scrollView removeObserver:self forKeyPath:@"contentOffset"]; [scrollView removeObserver:self forKeyPath:@"contentSize"]; @@ -463,9 +470,6 @@ - (void)startAnimating [self setScrollViewContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.offsetY) withComplitionBlock:^{ weakSelf.state = KoaPullToRefreshStateLoading; }]; -// [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.offsetY) animated:YES]; -// [self sets] - } - (void)setScrollViewContentOffset:(CGPoint)contentOffset withComplitionBlock:(void(^)())complitionBlock @@ -515,6 +519,7 @@ - (void)setState:(KoaPullToRefreshState)newState { break; case KoaPullToRefreshStateLoading: + self.programmaticallyLoading = NO; [self startRotatingIcon]; __weak void (^actionHandler)(void) = pullToRefreshActionHandler; @@ -539,7 +544,6 @@ - (void)startRotatingIcon { } - (void)stopRotatingIcon { - self.programmaticallyLoading = NO; [self.loaderLabel.layer removeAnimationForKey:@"Spin"]; } From ec1019e13a6eb6424730738d929128501d964eb2 Mon Sep 17 00:00:00 2001 From: Max Kuznetsov Date: Wed, 30 Jul 2014 12:46:32 +0300 Subject: [PATCH 16/21] fix bug with content inset and titleLabel alpha --- KoaPullToRefresh/KoaPullToRefresh.m | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index 7932dc1..e603980 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -94,7 +94,7 @@ - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler KoaPullToRefreshViewHeightShowed = pullToRefreshHeightShowed; KoaPullToRefreshViewTitleBottomMargin += pullToRefreshHeightShowed; - [self setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed, self.contentInset.left, self.contentInset.bottom, self.contentInset.right)]; + [self setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed + self.contentInset.top, self.contentInset.left, self.contentInset.bottom, self.contentInset.right)]; if (!self.pullToRefreshView) { @@ -124,6 +124,7 @@ - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler } self.pullToRefreshView.offsetY = programmingAnimationOffestY; +// self.pullToRefreshView.titleLabel.alpha = 1; } - (void)setPullToRefreshView:(KoaPullToRefreshView *)pullToRefreshView { @@ -315,8 +316,8 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N return; } - if (self.scrollView.contentOffset.y < -self.offsetY && self.programmaticallyLoading) { - self.scrollView.contentOffset = CGPointMake(0, -self.offsetY); + if (self.scrollView.contentOffset.y < -(self.offsetY + self.originalTopInset) && self.programmaticallyLoading) { + self.scrollView.contentOffset = CGPointMake(0, -(self.offsetY + self.originalTopInset)); } @@ -342,11 +343,15 @@ - (void)scrollViewDidScroll:(CGPoint)contentOffset } //Change title label alpha - [self.titleLabel setAlpha: ((contentOffset.y * -1) / KoaPullToRefreshViewHeight) - 0.1]; + CGFloat absOffset = fabsf(self.originalTopInset); + absOffset /= contentOffset.y; + absOffset = 1.4 + absOffset; + [self.titleLabel setAlpha:absOffset]; + if(self.state != KoaPullToRefreshStateLoading) { CGFloat scrollOffsetThreshold; - scrollOffsetThreshold = self.frame.origin.y-self.originalTopInset; + scrollOffsetThreshold = self.frame.origin.y - self.originalTopInset; if(!self.scrollView.isDragging && self.state == KoaPullToRefreshStateTriggered) self.state = KoaPullToRefreshStateLoading; @@ -366,14 +371,7 @@ - (void)scrollViewDidScroll:(CGPoint)contentOffset //Set content offset for special cases if(self.state != KoaPullToRefreshStateLoading) { if (self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed && self.scrollView.contentOffset.y < 0) { - [self.scrollView setContentInset:UIEdgeInsetsMake(abs(self.scrollView.contentOffset.y), - self.scrollView.contentInset.left, - self.scrollView.contentInset.bottom, - self.scrollView.contentInset.right)]; - } else if(self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed) { - [self.scrollView setContentInset:UIEdgeInsetsZero]; - } else { - [self.scrollView setContentInset:UIEdgeInsetsMake(KoaPullToRefreshViewHeightShowed, + [self.scrollView setContentInset:UIEdgeInsetsMake(self.originalTopInset + abs(self.scrollView.contentOffset.y), self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right)]; @@ -467,7 +465,8 @@ - (void)startAnimating [self layoutSubviews]; __weak KoaPullToRefreshView *weakSelf = self; - [self setScrollViewContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.offsetY) withComplitionBlock:^{ + [self setScrollViewContentOffset:CGPointMake(self.scrollView.contentOffset.x, -(self.originalTopInset + KoaPullToRefreshViewHeightShowed + self.frame.size.height)) + withComplitionBlock:^{ weakSelf.state = KoaPullToRefreshStateLoading; }]; } From 9394b920d26d6411a4e6eea054e293120738b0cb Mon Sep 17 00:00:00 2001 From: Max Kuznetsov Date: Mon, 4 Aug 2014 14:18:15 +0300 Subject: [PATCH 17/21] fix bug with observers leaks --- KoaPullToRefresh/KoaPullToRefresh.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index e603980..4ff13bf 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -139,9 +139,13 @@ - (KoaPullToRefreshView *)pullToRefreshView { return objc_getAssociatedObject(self, &UIScrollViewPullToRefreshView); } -- (void)setShowsPullToRefresh:(BOOL)showsPullToRefresh { +- (void)setShowsPullToRefresh:(BOOL)showsPullToRefresh +{ + if (!self.pullToRefreshView) { + return; + } + self.pullToRefreshView.hidden = !showsPullToRefresh; - if(!showsPullToRefresh) { if (self.pullToRefreshView.isObserving) { [self removeObserver:self.pullToRefreshView forKeyPath:@"contentOffset"]; From 13c16d1a6c1b56b9fabf61ac958ef16ba817c221 Mon Sep 17 00:00:00 2001 From: Max Kuznetsov Date: Mon, 4 Aug 2014 15:18:10 +0300 Subject: [PATCH 18/21] fix bug with offsets, disappearing refresh view --- KoaPullToRefresh/KoaPullToRefresh.m | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index 4ff13bf..7fe5763 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -267,10 +267,6 @@ - (void)layoutSubviews - (void)resetScrollViewContentInset { - if (self.disable) { - return; - } - UIEdgeInsets currentInsets = self.scrollView.contentInset; currentInsets.top = self.originalTopInset; @@ -286,10 +282,6 @@ - (void)resetScrollViewContentInset - (void)setScrollViewContentInsetForLoadingWithComplitionBlock:(void(^)())complitionBlock { - if (self.disable) { - return; - } - UIEdgeInsets currentInsets = self.scrollView.contentInset; //CGFloat offset = MAX(self.scrollView.contentOffset.y * -1, 0); //currentInsets.top = MIN(offset, self.originalTopInset + self.bounds.size.height); @@ -471,7 +463,9 @@ - (void)startAnimating __weak KoaPullToRefreshView *weakSelf = self; [self setScrollViewContentOffset:CGPointMake(self.scrollView.contentOffset.x, -(self.originalTopInset + KoaPullToRefreshViewHeightShowed + self.frame.size.height)) withComplitionBlock:^{ - weakSelf.state = KoaPullToRefreshStateLoading; + if (weakSelf.state != KoaPullToRefreshStateLoading) { +// weakSelf.state = KoaPullToRefreshStateLoading; + } }]; } @@ -489,7 +483,6 @@ - (void)setScrollViewContentOffset:(CGPoint)contentOffset withComplitionBlock:(v complitionBlock(); } }]; - } @@ -526,9 +519,10 @@ - (void)setState:(KoaPullToRefreshState)newState { [self startRotatingIcon]; __weak void (^actionHandler)(void) = pullToRefreshActionHandler; + __weak KoaPullToRefreshView *weakSelf = self; [self setScrollViewContentInsetForLoadingWithComplitionBlock:^{ if(previousState == KoaPullToRefreshStateTriggered && actionHandler) { - actionHandler(); + [weakSelf performSelector:@selector(runPullToRefreshActionHandler) withObject:nil afterDelay:0.3]; } }]; @@ -536,6 +530,11 @@ - (void)setState:(KoaPullToRefreshState)newState { } } +- (void)runPullToRefreshActionHandler +{ + pullToRefreshActionHandler(); +} + - (void)startRotatingIcon { CABasicAnimation *rotation; rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; From 02a4e8de15a329fa844aa2a266895786a3479068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Mo=CC=88ckel?= Date: Tue, 30 Sep 2014 14:09:43 +0200 Subject: [PATCH 19/21] Fixes from SMCorporation/KoaPullToRefresh --- KoaPullToRefresh/KoaPullToRefresh.m | 30 ++++++++++++----------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index 836a49b..7fe5763 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -237,33 +237,21 @@ - (void)layoutSubviews self.titleLabel.text = [self.titles objectAtIndex:self.state]; //Set title frame - - CGSize titleSize; - if ([self.titleLabel.text respondsToSelector:@selector(sizeWithAttributes:)]) { - titleSize = [self.titleLabel.text boundingRectWithSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: self.titleLabel.font} context:nil].size; - } else { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - titleSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) lineBreakMode:self.titleLabel.lineBreakMode]; -#pragma clang diagnostic pop - } - - - + CGSize titleSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) lineBreakMode:self.titleLabel.lineBreakMode]; CGFloat titleY = KoaPullToRefreshViewHeight - KoaPullToRefreshViewHeightShowed - titleSize.height - KoaPullToRefreshViewTitleBottomMargin; [self.titleLabel setFrame:CGRectIntegral(CGRectMake(0, titleY, self.frame.size.width, titleSize.height))]; //Set state of loader label switch (self.state) { - case KoaPullToRefreshStateStopped: + case KoaPullToRefreshStateStopped: [self.loaderLabel setAlpha:0]; [self.loaderLabel setFrame:CGRectMake(self.frame.size.width/2 - self.loaderLabel.frame.size.width/2, titleY - 100, self.loaderLabel.frame.size.width, self.loaderLabel.frame.size.height)]; break; - case KoaPullToRefreshStateTriggered: + case KoaPullToRefreshStateTriggered: [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionCurveEaseInOut animations:^{ [self.loaderLabel setAlpha:1]; [self.loaderLabel setFrame:CGRectMake(self.frame.size.width/2 - self.loaderLabel.frame.size.width/2, @@ -418,7 +406,7 @@ - (UILabel *)loaderLabel { - (NSString *)fontAwesomeIcon { if (!_fontAwesomeIcon) { - _fontAwesomeIcon = @"fa-refresh"; + _fontAwesomeIcon = @"icon-refresh"; } return _fontAwesomeIcon; } @@ -527,10 +515,16 @@ - (void)setState:(KoaPullToRefreshState)newState { break; case KoaPullToRefreshStateLoading: + self.programmaticallyLoading = NO; [self startRotatingIcon]; - if(previousState == KoaPullToRefreshStateTriggered && pullToRefreshActionHandler) - pullToRefreshActionHandler(); + __weak void (^actionHandler)(void) = pullToRefreshActionHandler; + __weak KoaPullToRefreshView *weakSelf = self; + [self setScrollViewContentInsetForLoadingWithComplitionBlock:^{ + if(previousState == KoaPullToRefreshStateTriggered && actionHandler) { + [weakSelf performSelector:@selector(runPullToRefreshActionHandler) withObject:nil afterDelay:0.3]; + } + }]; break; } From 82f977a29399454362644dac0e86fb0b27c8992c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Mo=CC=88ckel?= Date: Tue, 30 Sep 2014 15:04:03 +0200 Subject: [PATCH 20/21] fa-refresh --- KoaPullToRefresh/KoaPullToRefresh.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index 7fe5763..e3afd66 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -406,7 +406,7 @@ - (UILabel *)loaderLabel { - (NSString *)fontAwesomeIcon { if (!_fontAwesomeIcon) { - _fontAwesomeIcon = @"icon-refresh"; + _fontAwesomeIcon = @"fa-refresh"; } return _fontAwesomeIcon; } From 4ace5246d9300491344ca490b85fee4e9aa025ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Mo=CC=88ckel?= Date: Wed, 30 Sep 2015 11:52:22 +0200 Subject: [PATCH 21/21] New Fontawesome Icons, removed deprecation Warning --- .../project.pbxproj | 11 +- .../xcschemes/KoaPullToRefresh.xcscheme | 19 +- .../KoaPullToRefresh-Info.plist | 2 +- .../Resources/FontAwesome.ttf | Bin 64960 -> 138204 bytes .../Resources/NSString+FontAwesome.h | 889 ++++++++++++----- .../Resources/NSString+FontAwesome.m | 929 ++++++++++++------ .../Resources/UIFont+FontAwesome.h | 6 +- .../Resources/UIFont+FontAwesome.m | 9 +- Demo/KoaPullToRefresh/ViewController.m | 3 +- KoaPullToRefresh.podspec | 17 +- KoaPullToRefresh/KoaPullToRefresh.h | 4 - KoaPullToRefresh/KoaPullToRefresh.m | 17 +- 12 files changed, 1330 insertions(+), 576 deletions(-) diff --git a/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj b/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj index 9eb88cf..f39c29a 100644 --- a/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj +++ b/Demo/KoaPullToRefresh.xcodeproj/project.pbxproj @@ -172,7 +172,7 @@ 555AC05F173B93B0001EAC94 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0460; + LastUpgradeCheck = 0700; ORGANIZATIONNAME = "Sergi Gracia"; }; buildConfigurationList = 555AC062173B93B0001EAC94 /* Build configuration list for PBXProject "KoaPullToRefresh" */; @@ -261,6 +261,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -272,7 +273,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -296,7 +297,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -309,7 +310,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "KoaPullToRefresh/KoaPullToRefresh-Prefix.pch"; INFOPLIST_FILE = "KoaPullToRefresh/KoaPullToRefresh-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.sergigracia.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -321,7 +322,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "KoaPullToRefresh/KoaPullToRefresh-Prefix.pch"; INFOPLIST_FILE = "KoaPullToRefresh/KoaPullToRefresh-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.sergigracia.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/Demo/KoaPullToRefresh.xcodeproj/xcshareddata/xcschemes/KoaPullToRefresh.xcscheme b/Demo/KoaPullToRefresh.xcodeproj/xcshareddata/xcschemes/KoaPullToRefresh.xcscheme index 7ea9c82..b22fbfc 100644 --- a/Demo/KoaPullToRefresh.xcodeproj/xcshareddata/xcschemes/KoaPullToRefresh.xcscheme +++ b/Demo/KoaPullToRefresh.xcodeproj/xcshareddata/xcschemes/KoaPullToRefresh.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -38,17 +38,21 @@ ReferencedContainer = "container:KoaPullToRefresh.xcodeproj"> + + - + - + CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.sergigracia.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Demo/KoaPullToRefresh/Resources/FontAwesome.ttf b/Demo/KoaPullToRefresh/Resources/FontAwesome.ttf index 908f69ec9a701858116376eee7b3e4ecb76da25b..d7994e13086b1ac1a216bd754c93e1bccd65f237 100755 GIT binary patch delta 80461 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 X9_j-g>I0qv=nCbg{cc~iLh=6rISR5W delta 9360 zcma)i33OD)m3G~#xAywF`}J$7wb0#CzZReksTU!HXoL|UiCx&3MMxNs%pznKv&28$ zG1w#+GdArYoOmH5w!!g|SaF@4!c=6EvpjN|P%AhrHmEwMOf z@@Le%_iDX$?^n0#eYYOJeNGv?#8LzZAr6uzjC3|Px6faH-H$XZ`2erNIoHi@hTTLU z1Qg5%7A~!-xr^>~W4;XYoi}ai>SGW7>ICM$MhI=`?%Ljm<=CIShEJt?^PUZ>_BNl# z{BH>v`fktqu60z}w1$v((^wzx=~fnn@e7ve)3=V^VjWjZ?EQwbI;tXjUz!w9xovj^8hV)NBc2{ zMu_jgJwzmea9F6t{GDS@x}B^LYBRtJ^}apZwv!|Ye1=1fVhf2tN#<4vPq_}^0MOs0yqJhC;=m&LNU{1aMzSO9ZmbLIk zqkkM-H@bTC#?kiCSwogTT=>ItzyIua7k~GU0l!wD`L#UFrx}`8(>0Ig)?AvVF^y`V z5$C8g>l|?oJ1^PLP&8p~rk6b>`xG%>C3%?7&ol^AWds5haSq%jTylzjG;2fVHvLI& zS|nncD8x!85KBzm~$NA0a{-_4AMdg8l$eGbDL+!zW7y zDiN=OM#$(zfg~Ml-PmddW{bKusOjSDfSFBGa_qHZELm4Jj273G1wes5Py%Ijl*C$F zW8ntZdrrUK`JSr*!kNWI1p`}(R!b7GAS8PR&X-tON+pYNOjb;56K2GOl0-cB^T0Il zc?{o|eqLP;Ma+_rlSXF%wu@HLuq30h*sP`)dZ7hfXsZoEU zS1*lobKTy^RDUFIqG30xs_LW^Eb3d`xv=hRy|BN|W|OK`WgClHeJ=le=8brP zHf7(dUd(=zZ3GH*&CvswvI}La=G3CJhrZ^`20l(~xTAjKtR+(vk05y?Zih`#sFhX( z3+)zLv1{AAbmni8`UIQTDoCub*k#cb2S+^T7GhdVaoodXJt1MEwgzpAMI(qqNl5m} z9-Z+rUV?cv(g`|@;}efD${X@u6;wc?CSF^^=PQR;F?e+ZMn?1y5}v|e6_^OkMhH=C%lut^|@Za`>6|0K8HBBw^ZeOzF=k0FIeiZ_dJ>X*h$aH zw?Ew1+G;Nk?tO6WLI0oqHsM{a*<{z6T1s79+(~pHQg6%1}ex>BAyJ} zY^qRhOgAUnC`%?vi$Rj9Tg-E-9?!m)Cf?DqZy9(zdN_F(*plUoV`W}=aK^zJ(~v0b zc2LCA<0&#cHqALQ^q&=SN_R@4SX4B@0+b1M3N|^nOXC8$h*sWA?jXeD z!-<^%zM#*D&!9EFLYM$DpH?$cnR9{=nj=dSz~zy-k-4QXHuKy}URPqqBC)ZR6^}48 z9?dyUNl3EE4k|mK#EiINkhyzeL27Ya|EJqM+y529AxEJsPjd2^5h6wTMT%3Qc85IY zYm-Ak3k3#Xn}WMwowHaMnM3cLKljn)_f{Jey!ChKDpRP49R*1-dna$x>~6nRDv--< z()plU->28(f<0RMxrb@c&{lTBWhH$P6D0;OVCrF7r0>J^_OVaf6|Zt z!UDOR8b+_ex8mrXxjnjvqz+sGT>QI$$NpDI0{k?(0n zQ3`^wXxukG3vdP+|Hd?QKQ*!AZ%xCJ{)+s|(;$hI<|d)$L&ud#5Z}qcFnk3D4hV;z zrT!lL(fA19rA0KS3vrYPgW9ynCqY7=v7Jo8rF zN-@m~GxbvsifJj0sh6g%6mJt#;(?4=|F2jkVHurvx!u}n*pBZHng5!$9BB)_G5ur{%yk-Izx~$?2XCXu{jO+-9>EZCEaBDc6^}~fQCN_oXU1PUg zChN}@m>V(4l?AeM^jV=5W%@9q%P0gVF&0gz{El;3;{!uz4WrzR;qta{7%pV};c#2& z=29Gn4n`v*J8_IiG=??s9)Gr)CYF(b1=ByYh0=&gJNfNu0SDvFb%1E{|~+i2};xb zqu+!W#QGP03#tZ2+Mj?3vhdNgoW@O>q2pSK6X|0Ws^SW|uD$vj?GRjpG@7QbUXb?K z|1xOzcX0 zO*@(d-VI^RC^!7y6yL?hn5Ku6pdyJ9+(@QD40oL(DDl?j6uU|=YlAh0Sm1kULS66E z#}Dk^4-(vWde?Ar*Xh%{*x;_ybmQAwrbOPp=kEP)kK94O0-s;4I*kT%;|Ut?#Ca{i z@gf6rm(LR*J#ci@GUtt0%ZT_9@uD6V;8&;y-4;_xR&a{QQqc zB2`|Ay_S7<_$;e~!ted)C)s!Hp^^a3F&TX)ZmNX4=kIeY4f_F`dK)ajRGo=&DK5}ZQFS4*v7W#x8dJFdgMjj z?cvPZ#0*6$nS;q@ zJYwRz4*0*0s2P(YhA$!+UL!}=WgRyz?1Gg!QWi6isfK*RmM%1|;Z9#2HjCgGnB}GjX!G%$j z#rYq0<~`%M87ATpBZ2mzbj%o-<&Stnt`c|85?+MX#rZR*EOr>{=xd~j_zZk`N93sK zfJh2;sX_V~H)S({h@p!+kzAT68ZU&?s70oRLpcC-z&p2&KV`{~<54u&kfm6hv$>Fr zbU)Y68-k zNYZ7WWF$~#F~fG)1x2NB?3`?l6e<=$b9fd0L&}qDXkdXbRu&gdTOA$>DljHX*_ei5 zhGmLu2QiOf3_?9p4+b1tk#_FM9{O_lD_BI?fMT0hR^2jVZkbvcScH@+sR~fVDanO0 zxR_u8(I$vYz<5*?1xaRts`*NT*hZuD0w7K#$HTSa7_GLKel^r^yB#Ai$DhUFhO&}BthD*lY1q>OL zA}FGjT2)0wNmNs;R+u2=$vnVPz^aOpq}mlp3^5T2u8>DPg5XA`Mr{`6W==ydV7lzI zC`Ewb!5pt5*;Oxw2{xQq#Y$B#MrsPqzeGW@Fw|KDijj)qv|BAU#6bdZ8BDI{>hO#c zc_9^5!C>50uqt^vxCEw1esPLxqAV+RMW7A}MHJmAW)Z1i6FoAb=~5lYad5%}z&KG6 z5EOK}(qk!{Nq){fOXaR^5 zsK%I`$Et!wQkjNxLD3}?jN${T1$X>+WGCW}#n=Rct>-CvMXA6fCSVQ?SVE~xCs2Cn z0}uxO`Y7ci(L!xF2M$1&qfBEMrN|V=QhZEG6-u&Q1(iuYijf`_HJ}nYkjAL$v4agK z1we8LK8&D%scxW-(tCfxOhH#wkKkl7IX!^j1wp;sJ{v}47F`mS;hrJt&-@bI=BTqc))zV->TrOP#?I_WBHn* z1q|IlN(s~kpbOZGN*d0zEHV)nr>LTrTM=R_^9jr%3pUAa<15q7UB|9UIFO<##gZW6 z!H58wCgfX0w}h@DpnK%0h#PY#U}1iXV6mf*^XP?P^Cu;Y%q9VrZf#`&9%gzzM;8=1Z?BaetQ zGGw&HNSb9AKit4~s0VpQsFESGsI4icVHc+zcu-U+#G;K1U&oa!Qkw|k-ir;8=M@1b zU_o!tRqLXUTCxY$++UElqPHgza7j~K6`oR8z9pq*-~Lm7_u~Q6`@s!ewX2fVzV6jc z8yf@c)ziDO<&pAP^JkS;HqESzO_4O!DjqzTZ9VjQ+sS>LERGT+t3c9I&EPF7D`w*R zPYBsUu26nyFaj;|0{FqL;`IDk@Z`EZ(WN~-Rh@^H?7OpgB(UrBy!NJB=FP5|R-7tL zPHWzA^xjIzB04O|`D^w)b$VAPXFWO5oY!!K#yDRgsUSCztvTMO@FNZf^XhnpSkp*Z zw2~s_#Vn#0XF(a?OkO=#FY?2%U=FuLBjdyj-{S}*XK0C391tHwDaKJ^n^jA`tJG8B znj*P^@t(f+_?+$glG8SIBz6amo0=+vv1Bq9JbXO+ z>9jpx>1YTC(kJh0OA3;OmKA^F^)q*M2%9hCG{+kWmgXZswh->NrF9(**Dc*Ny*NMC z!5(ZlxNpg!&Z?fCrO`cf#=?q|%UiZLPn%Kduc@q=KIf*XC-&~wt7dPRHN7RddWw%O zZL;~a0!94i`wstZf_`}bjvIR3@?+;@q_O5hrRab#O4w}!iymI7Ttj9n{))=}uL&$m z{$1YsH>s*L##ILzPE~+cHprF_O)nU9q+>Vi?!|is^L4LoQ z9>%c$@0`;^XRar|eS9S~a`gXue2*b3cRD<17`XZIZ7u|khggF|C9WKgo=B#UsbnTb zihM?lttYnpQav5d!$-@eHMF-kOrs(ODyEOfs-~){rs3V~?YrBv@9|!(w2AlX7)UPDdb!8*DgMT_$R+rwtdL+4e|Nhlh2w;b<9-ycb? zI&feWZ@(Wkz(5-Ra(Y}2rZH~9y)AY5qev~dq9$e}EH!Xri?gdAO{N2a&rWa!#?)Ye zYqdL(bC*GW7jl|j9(lO)8kOK|&dS^kb;-G=LnEB=}{sn%L*?9H^ z34^RBrG1(5UmoMhG#*`@{pEHBodXT$YC&9!$BM-RJ6@4!?ifl=4W!Rc5-4GrCtiCS zN;6-3{X5H^K>7Uehy^{IH{)+IPX}2Lf_RWGJ@G>J{IdcRY!aYv`yZW%1o3lXkR&N5#5P!w-ja z2|qoVcqnk?gb2Ah78{wH|E)B2xtt%4u|YFxno+h+G5UUyeJtCVee4%~hN3u!EJzTB zoC=n|^YkG9m^4`5i~($O{aEJdcgC7o^RSh0feSH*+x4%%yMO>bJ}!V7PWA+{ZYI zf2$Jk%hT0wQ8H`;+4LvtT@j9Bp)1pjhhU9UVxiOki+@5WOv@jWlj1qj=|%uK9zO{ullXWe&aoc;B&S|L1>(uT#I+|J9FS86}qfH$R3$76L+= z#PHhL-}ebb`ZJ$E8SL$U;S=yDh$f~{0$yA*esO7-kMWC-&g*jZ_{33?xpw_se*wKe z_$e$by{y6IHaU4HBPWaZ#i{7mKF8+iPrwyP6ECm9R^sK+#z)b{pWCq<`iDNn4;Z9B z@EJ7W2kHKGpFx@Z+9AaL`#*y<#Zn+Q!qw4mL@r0jUH!)AP(FuH9F6kM{LFa#*-0^v z*ILvM&r4Ao#5h-n<=EbiD=pU+(+tZ?<^Fp=22cM3pMw=>|EbTx#F<8ctpEEL(YV_# z!LbMTJN(p+K$+U>}~dK_U9cd9A}*6&b7`Lv|jCm z_Ju3y8g#F4zw9}pFVG+NO5RTI^Ts;k4c}bfZN9U4w!Heh4S7%HoB7}MJN&o$AN7Aw zP*_k`u({w+!SjWru)1(<;o-vPi=?9ZqWg;8C{Ct|k59;(uy4Yv0X@(bI1o4!_#)U4 zJRJOO$Q`N--5Gkdq@m=gk}paZl)e!*!+UY1oyV^YJ0d3{=gS()j+H$>kxYzF+&pn` zQee{clb)X(D!;w_i;5$aWt9smAFUFq+N&O@x>&uudT`3oDWBJ*Yd)_!3 z9+-Ki>48~v*4kMw&-&AKmDe4geckLgo6~bv%{eo-a_$53lzGQns#^}XJl=A)@#6x2G1LT2i^>fhBJ)EnM2Z z^qF>J+4ryi;D%do`2F(g<*SyTTK?&c$r}&f_~wez6$@7EUU728%PaMjYge9F`Ti>Z zs#{mRy1IV#^3@OE@An;ZJ09)$uQjXI{Hn98^HA63u0O3kvi6mm;x`??>B2f~-MV$J zu0Of{;)aF|eH-5DZtC9FJ>1jQbEaq3=Qppo`RvBLjm;bH-1yQaWz*bEyEi?w+1R{s z^UGVbElaixZuz{ot#@DVOTAxgE!(kECPZwdeLH4d%x7}3A6kLIWBvoT)MNc$2u_r>wFjMCp6Pb(x3_Kv4j zqQg<1UV;N#$s~Amyy7e|;QV;{m!ujlkfmfEX(Iu$ko4i_=w3`UBf;(^J22ITA0ltc zm2Ss-069-3nbO}$sjvTSjAet(*lPj4Y1)tpHIaJEwPWwuWI0)c=_RCntZfCQ0Z%RO zi&r(uslodcQu`cAa>C*pQ1)7~;mW9Et(wU;96dnhlPEAW4Q=mxZ64o^f0hK%G0xr-bkcawXbYZqvm_Lr;lR$+E^b#?!vD!oG# zHr%{<{c}+Z{by#VJ9>6*S-XAB&OYmSYTeddz0VmAI)jNyuHhONU5n>FYig%Nafro- Jhwdfh{{fC^db9ul diff --git a/Demo/KoaPullToRefresh/Resources/NSString+FontAwesome.h b/Demo/KoaPullToRefresh/Resources/NSString+FontAwesome.h index 2f1c618..cf52d15 100755 --- a/Demo/KoaPullToRefresh/Resources/NSString+FontAwesome.h +++ b/Demo/KoaPullToRefresh/Resources/NSString+FontAwesome.h @@ -26,272 +26,647 @@ static NSString *const kFontAwesomeFamilyName = @"FontAwesome"; +/** + @abstract FontAwesome Icons. + */ typedef NS_ENUM(NSInteger, FAIcon) { - FAIconGlass = 0, - FAIconMusic, - FAIconSearch, - FAIconEnvelope, - FAIconHeart, - FAIconStar, - FAIconStarEmpty, - FAIconUser, - FAIconFilm, - FAIconThLarge, - FAIconTh, - FAIconThList, - FAIconOk, - FAIconRemove, - FAIconZoomIn, - FAIconZoomOut, - FAIconOff, - FAIconSignal, - FAIconCog, - FAIconTrash, - FAIconHome, - FAIconFile, - FAIconTime, - FAIconRoad, - FAIconDownloadAlt, - FAIconDownload, - FAIconUpload, - FAIconInbox, - FAIconPlayCircle, - FAIconRepeat, - FAIconRefresh, - FAIconListAlt, - FAIconLock, - FAIconFlag, - FAIconHeadphones, - FAIconVolumeOff, - FAIconVolumeDown, - FAIconVolumeUp, - FAIconQrcode, - FAIconBarcode, - FAIconTag, - FAIconTags, - FAIconBook, - FAIconBookmark, - FAIconPrint, - FAIconCamera, - FAIconFont, - FAIconBold, - FAIconItalic, - FAIconTextHeight, - FAIconTextWidth, - FAIconAlignLeft, - FAIconAlignCenter, - FAIconAlignRight, - FAIconAlignJustify, - FAIconList, - FAIconIndentLeft, - FAIconIndentRight, - FAIconFacetimeVideo, - FAIconPicture, - FAIconPencil, - FAIconMapMarker, - FAIconAdjust, - FAIconTint, - FAIconEdit, - FAIconShare, - FAIconCheck, - FAIconMove, - FAIconStepBackward, - FAIconFastBackward, - FAIconBackward, - FAIconPlay, - FAIconPause, - FAIconStop, - FAIconForward, - FAIconFastForward, - FAIconStepForward, - FAIconEject, - FAIconChevronLeft, - FAIconChevronRight, - FAIconPlusSign, - FAIconMinusSign, - FAIconRemoveSign, - FAIconOkSign, - FAIconQuestionSign, - FAIconInfoSign, - FAIconScreenshot, - FAIconRemoveCircle, - FAIconOkCircle, - FAIconBanCircle, - FAIconArrowLeft, - FAIconArrowRight, - FAIconArrowUp, - FAIconArrowDown, - FAIconShareAlt, - FAIconResizeFull, - FAIconResizeSmall, - FAIconPlus, - FAIconMinus, - FAIconAsterisk, - FAIconExclamationSign, - FAIconGift, - FAIconLeaf, - FAIconFire, - FAIconEyeOpen, - FAIconEyeClose, - FAIconWarningSign, - FAIconPlane, - FAIconCalendar, - FAIconRandom, - FAIconComment, - FAIconMagnet, - FAIconChevronUp, - FAIconChevronDown, - FAIconRetweet, - FAIconShoppingCart, - FAIconFolderClose, - FAIconFolderOpen, - FAIconResizeVertical, - FAIconResizeHorizontal, - FAIconBarChart, - FAIconTwitterSign, - FAIconFacebookSign, - FAIconCameraRetro, - FAIconKey, - FAIconCogs, - FAIconComments, - FAIconThumbsUp, - FAIconThumbsDown, - FAIconStarHalf, - FAIconHeartEmpty, - FAIconSignout, - FAIconLinkedinSign, - FAIconPushpin, - FAIconExternalLink, - FAIconSignin, - FAIconTrophy, - FAIconGithubSign, - FAIconUploadAlt, - FAIconLemon, - FAIconPhone, - FAIconCheckEmpty, - FAIconBookmarkEmpty, - FAIconPhoneSign, - FAIconTwitter, - FAIconFacebook, - FAIconGithub, - FAIconUnlock, - FAIconCreditCard, - FAIconRss, - FAIconHdd, - FAIconBullhorn, - FAIconBell, - FAIconCertificate, - FAIconHandRight, - FAIconHandLeft, - FAIconHandUp, - FAIconHandDown, - FAIconCircleArrowLeft, - FAIconCircleArrowRight, - FAIconCircleArrowUp, - FAIconCircleArrowDown, - FAIconGlobe, - FAIconWrench, - FAIconTasks, - FAIconFilter, - FAIconBriefcase, - FAIconFullscreen, - FAIconGroup, - FAIconLink, - FAIconCloud, - FAIconBeaker, - FAIconCut, - FAIconCopy, - FAIconPaperClip, - FAIconSave, - FAIconSignBlank, - FAIconReorder, - FAIconListUl, - FAIconListOl, - FAIconStrikethrough, - FAIconUnderline, - FAIconTable, - FAIconMagic, - FAIconTruck, - FAIconPinterest, - FAIconPinterestSign, - FAIconGooglePlusSign, - FAIconGooglePlus, - FAIconMoney, - FAIconCaretDown, - FAIconCaretUp, - FAIconCaretLeft, - FAIconCaretRight, - FAIconColumns, - FAIconSort, - FAIconSortDown, - FAIconSortUp, - FAIconEnvelopeAlt, - FAIconLinkedin, - FAIconUndo, - FAIconLegal, - FAIconDashboard, - FAIconCommentAlt, - FAIconCommentsAlt, - FAIconBolt, - FAIconSitemap, - FAIconUmbrella, - FAIconPaste, - FAIconUserMd, - FAIconStethoscope, - FAIconBuilding, - FAIconHospital, - FAIconAmbulance, - FAIconMedkit, - FAIconHSign, - FAIconPlusSignAlt, - FAIconSpinner, - FAIconCloudDownload, - FAIconCloudUpload, - FAIconLightbulb, - FAIconExchange, - FAIconBellAlt, - FAIconFileAlt, - FAIconBeer, - FAIconCoffee, - FAIconFood, - FAIconFighterJet, - FAIconAngleLeft, - FAIconAngleRight, - FAIconAngleUp, - FAIconAngleDown, - FAIconDoubleAngleLeft, - FAIconDoubleAngleRight, - FAIconDoubleAngleUp, - FAIconDoubleAngleDown, - FAIconCircleBlank, - FAIconCircle, - FAIconDesktop, - FAIconLaptop, - FAIconTablet, - FAIconMobilePhone, - FAIconQuoteLeft, - FAIconQuoteRight, - FAIconReply, - FAIconGithubAlt, - FAIconFolderCloseAlt, - FAIconFolderOpenAlt, - FAIconSuitcase, + FAGlass, + FAMusic, + FASearch, + FAEnvelopeO, + FAHeart, + FAStar, + FAStarO, + FAUser, + FAFilm, + FAThLarge, + FATh, + FAThList, + FACheck, + FATimes, + FASearchPlus, + FASearchMinus, + FAPowerOff, + FASignal, + FACog, + FATrashO, + FAHome, + FAFileO, + FAClockO, + FARoad, + FADownload, + FAArrowCircleODown, + FAArrowCircleOUp, + FAInbox, + FAPlayCircleO, + FARepeat, + FARefresh, + FAListAlt, + FALock, + FAFlag, + FAHeadphones, + FAVolumeOff, + FAVolumeDown, + FAVolumeUp, + FAQrcode, + FABarcode, + FATag, + FATags, + FABook, + FABookmark, + FAPrint, + FACamera, + FAFont, + FABold, + FAItalic, + FATextHeight, + FATextWidth, + FAAlignLeft, + FAAlignCenter, + FAAlignRight, + FAAlignJustify, + FAList, + FAOutdent, + FAIndent, + FAVideoCamera, + FAPictureO, + FAPencil, + FAMapMarker, + FAAdjust, + FATint, + FAPencilSquareO, + FAShareSquareO, + FACheckSquareO, + FAArrows, + FAStepBackward, + FAFastBackward, + FABackward, + FAPlay, + FAPause, + FAStop, + FAForward, + FAFastForward, + FAStepForward, + FAEject, + FAChevronLeft, + FAChevronRight, + FAPlusCircle, + FAMinusCircle, + FATimesCircle, + FACheckCircle, + FAQuestionCircle, + FAInfoCircle, + FACrosshairs, + FATimesCircleO, + FACheckCircleO, + FABan, + FAArrowLeft, + FAArrowRight, + FAArrowUp, + FAArrowDown, + FAShare, + FAExpand, + FACompress, + FAPlus, + FAMinus, + FAAsterisk, + FAExclamationCircle, + FAGift, + FALeaf, + FAFire, + FAEye, + FAEyeSlash, + FAExclamationTriangle, + FAPlane, + FACalendar, + FARandom, + FAComment, + FAMagnet, + FAChevronUp, + FAChevronDown, + FARetweet, + FAShoppingCart, + FAFolder, + FAFolderOpen, + FAArrowsV, + FAArrowsH, + FABarChartO, + FATwitterSquare, + FAFacebookSquare, + FACameraRetro, + FAKey, + FACogs, + FAComments, + FAThumbsOUp, + FAThumbsODown, + FAStarHalf, + FAHeartO, + FASignOut, + FALinkedinSquare, + FAThumbTack, + FAExternalLink, + FASignIn, + FATrophy, + FAGithubSquare, + FAUpload, + FALemonO, + FAPhone, + FASquareO, + FABookmarkO, + FAPhoneSquare, + FATwitter, + FAFacebook, + FAGithub, + FAUnlock, + FACreditCard, + FARss, + FAHddO, + FABullhorn, + FABell, + FACertificate, + FAHandORight, + FAHandOLeft, + FAHandOUp, + FAHandODown, + FAArrowCircleLeft, + FAArrowCircleRight, + FAArrowCircleUp, + FAArrowCircleDown, + FAGlobe, + FAWrench, + FATasks, + FAFilter, + FABriefcase, + FAArrowsAlt, + FAUsers, + FALink, + FACloud, + FAFlask, + FAScissors, + FAFilesO, + FAPaperclip, + FAFloppyO, + FASquare, + FABars, + FAListUl, + FAListOl, + FAStrikethrough, + FAUnderline, + FATable, + FAMagic, + FATruck, + FAPinterest, + FAPinterestSquare, + FAGooglePlusSquare, + FAGooglePlus, + FAMoney, + FACaretDown, + FACaretUp, + FACaretLeft, + FACaretRight, + FAColumns, + FASort, + FASortAsc, + FASortDesc, + FAEnvelope, + FALinkedin, + FAUndo, + FAGavel, + FATachometer, + FACommentO, + FACommentsO, + FABolt, + FASitemap, + FAUmbrella, + FAClipboard, + FALightbulbO, + FAExchange, + FACloudDownload, + FACloudUpload, + FAUserMd, + FAStethoscope, + FASuitcase, + FABellO, + FACoffee, + FACutlery, + FAFileTextO, + FABuildingO, + FAHospitalO, + FAAmbulance, + FAMedkit, + FAFighterJet, + FABeer, + FAHSquare, + FAPlusSquare, + FAAngleDoubleLeft, + FAAngleDoubleRight, + FAAngleDoubleUp, + FAAngleDoubleDown, + FAAngleLeft, + FAAngleRight, + FAAngleUp, + FAAngleDown, + FADesktop, + FALaptop, + FATablet, + FAMobile, + FACircleO, + FAQuoteLeft, + FAQuoteRight, + FASpinner, + FACircle, + FAReply, + FAGithubAlt, + FAFolderO, + FAFolderOpenO, + FASmileO, + FAFrownO, + FAMehO, + FAGamepad, + FAKeyboardO, + FAFlagO, + FAFlagCheckered, + FATerminal, + FACode, + FAReplyAll, + FAMailReplyAll, + FAStarHalfO, + FALocationArrow, + FACrop, + FACodeFork, + FAChainBroken, + FAQuestion, + FAInfo, + FAExclamation, + FASuperscript, + FASubscript, + FAEraser, + FAPuzzlePiece, + FAMicrophone, + FAMicrophoneSlash, + FAShield, + FACalendarO, + FAFireExtinguisher, + FARocket, + FAMaxcdn, + FAChevronCircleLeft, + FAChevronCircleRight, + FAChevronCircleUp, + FAChevronCircleDown, + FAHtml5, + FACss3, + FAAnchor, + FAUnlockAlt, + FABullseye, + FAEllipsisH, + FAEllipsisV, + FARssSquare, + FAPlayCircle, + FATicket, + FAMinusSquare, + FAMinusSquareO, + FALevelUp, + FALevelDown, + FACheckSquare, + FAPencilSquare, + FAExternalLinkSquare, + FAShareSquare, + FACompass, + FACaretSquareODown, + FACaretSquareOUp, + FACaretSquareORight, + FAEur, + FAGbp, + FAUsd, + FAInr, + FAJpy, + FARub, + FAKrw, + FABtc, + FAFile, + FAFileText, + FASortAlphaAsc, + FASortAlphaDesc, + FASortAmountAsc, + FASortAmountDesc, + FASortNumericAsc, + FASortNumericDesc, + FAThumbsUp, + FAThumbsDown, + FAYoutubeSquare, + FAYoutube, + FAXing, + FAXingSquare, + FAYoutubePlay, + FADropbox, + FAStackOverflow, + FAInstagram, + FAFlickr, + FAAdn, + FABitbucket, + FABitbucketSquare, + FATumblr, + FATumblrSquare, + FALongArrowDown, + FALongArrowUp, + FALongArrowLeft, + FALongArrowRight, + FAApple, + FAWindows, + FAAndroid, + FALinux, + FADribbble, + FASkype, + FAFoursquare, + FATrello, + FAFemale, + FAMale, + FAGittip, + FASunO, + FAMoonO, + FAArchive, + FABug, + FAVk, + FAWeibo, + FARenren, + FAPagelines, + FAStackExchange, + FAArrowCircleORight, + FAArrowCircleOLeft, + FACaretSquareOLeft, + FADotCircleO, + FAWheelchair, + FAVimeoSquare, + FATry, + FAPlusSquareO, + + /* FontAwesome ver 4.1.0 */ + FAautomobile, + FAbank, + FAbehance, + FAbehanceSquare, + FAbomb, + FAbuilding, + FAcab, + FAcar, + FAchild, + FAcircleONotch, + FAcircleThin, + FAcodepen, + FAcube, + FAcubes, + FAdatabase, + FAdelicious, + FAdeviantart, + FAdigg, + FAdrupal, + FAempire, + FAenvelopeSquare, + FAfax, + FAfileArchiveO, + FAfileAudioO, + FAfileCodeO, + FAfileExcelO, + FAfileImageO, + FAfileMovieO, + FAfilePdfO, + FAfilePhotoO, + FAfilePictureO, + FAfilePowerpointO, + FAfileSoundO, + FAfileVideoO, + FAfileWordO, + FAfileZipO, + FAge, + FAgit, + FAgitSquare, + FAgoogle, + FAgraduationCap, + FAhackerNews, + FAheader, + FAhistory, + FAinstitution, + FAjoomla, + FAjsfiddle, + FAlanguage, + FAlifeBouy, + FAlifeRing, + FAlifeSaver, + FAmortarBoard, + FAopenid, + FApaperPlane, + FApaperPlaneO, + FAparagraph, + FApaw, + FApiedPiper, + FApiedPiperalt, + FApiedPipersquare, + FAqq, + FAra, + FArebel, + FArecycle, + FAreddit, + FAredditSquare, + FAsend, + FAsendO, + FAshareAlt, + FAshareAltSquare, + FAslack, + FAsliders, + FAsoundcloud, + FAspaceShuttle, + FAspoon, + FAspotify, + FAsteam, + FAsteamSquare, + FAstumbleupon, + FAstumbleuponCircle, + FAsupport, + FAtaxi, + FAtencentWeibo, + FAtree, + FAuniversity, + FAvine, + FAwechat, + FAweixin, + FAwordpress, + FAyahoo, + + /* FontAwesome ver 4.2.0 */ + FAangellist, + FAareaChart, + FAat, + FAbellSlash, + FAbellSlashO, + FAbicycle, + FAbinoculars, + FAbirthdayCake, + FAbus, + FAcalculator, + FAcc, + FAccAmex, + FAccDiscover, + FAccMastercard, + FAccPaypal, + FAccStripe, + FAccVisa, + FAcopyright, + FAeyedropper, + FAfutbolO, + FAgoogleWallet, + FAils, + FAioxhost, + FAlastfm, + FAlastfmSquare, + FAlineChart, + FAmeanpath, + FAnewspaperO, + FApaintBrush, + FApaypal, + FApieChart, + FAplug, + FAshekel, + FAsheqel, + FAslideshare, + FAsoccerBallO, + FAtoggleOff, + FAtoggleOn, + FAtrash, + FAtty, + FAtwitch, + FAwifi, + FAyelp, + + /* FontAwesome ver 4.3.0 */ + FAbed, + FAbuysellads, + FAcartArrowDown, + FAcartPlus, + FAconnectdevelop, + FAdashcube, + FAdiamond, + FAfacebookOfficial, + FAforumbee, + FAheartbeat, + FAhotel, + FAleanpub, + FAmars, + FAmarsDouble, + FAmarsStroke, + FAmarsStrokeH, + FAmarsStrokeV, + FAmedium, + FAmercury, + FAmotorcycle, + FAneuter, + FApinterestP, + FAsellsy, + FAserver, + FAship, + FAshirtsinbulk, + FAsimplybuilt, + FAskyatlas, + FAstreetView, + FAsubway, + FAtrain, + FAtransgender, + FAtransgenderAlt, + FAuserPlus, + FAuserSecret, + FAuserTimes, + FAvenus, + FAvenusDouble, + FAvenusMars, + FAviacoin, + + /* FontAwesome ver 4.4.0 */ + FA500px, + FAamazon, + FAbalanceScale, + FAbatteryEmpty, + FAbatteryFull, + FAbatteryHalf, + FAbatteryQuarter, + FAbatteryThreeQuarters, + FAblackTie, + FAcalendarCheckO, + FAcalendarMinusO, + FAcalendarPlusO, + FAcalendarTimesO, + FAccDinersClub, + FAccJcb, + FAchrome, + FAclone, + FAcommenting, + FAcommentingO, + FAcontao, + FAcreativeCommons, + FAexpeditedssl, + FAfirefox, + FAfonticons, + FAgenderless, + FAgetPocket, + FAgg, + FAggCircle, + FAhandLizardO, + FAhandPaperO, + FAhandPeaceO, + FAhandPointerO, + FAhandRockO, + FAhandScissorsO, + FAhandSpockO, + FAhourglass, + FAhourglassEnd, + FAhourglassHalf, + FAhourglassO, + FAhourglassStart, + FAhouzz, + FAiCursor, + FAindustry, + FAinternetExplorer, + FAmap, + FAmapO, + FAmapPin, + FAmapSigns, + FAmousePointer, + FAobjectGroup, + FAobjectUngroup, + FAodnoklassniki, + FAodnoklassnikiSquare, + FAopencart, + FAopera, + FAoptinMonster, + FAregistered, + FAsafari, + FAstickyNote, + FAstickyNoteO, + FAtelevision, + FAtrademark, + FAtripadvisor, + FAvimeo, + FAwikipediaW, + FAyCombinator }; + + @interface NSString (FontAwesome) -/* Returns the correct enum for a font-awesome icon. - * The list of identifiers can be found here: - * http://fortawesome.github.com/Font-Awesome/#all-icons */ +/** + @abstract Returns the correct enum for a font-awesome icon. + @discussion The list of identifiers can be found here: http://fortawesome.github.io/Font-Awesome/icons + */ + (FAIcon)fontAwesomeEnumForIconIdentifier:(NSString*)string; -/* Returns the font-awesome character associated to the - * icon enum passed as argument */ +/** + @abstract Returns the font-awesome character associated to the icon enum passed as argument + */ + (NSString*)fontAwesomeIconStringForEnum:(FAIcon)value; -/* Returns the font-awesome character associated to the font-awesome - * identifier. - * http://fortawesome.github.com/Font-Awesome/#all-icons */ +/* + @abstract Returns the font-awesome character associated to the font-awesome identifier. + @discussion The list of identifiers can be found here: http://fortawesome.github.io/Font-Awesome/icons + */ + (NSString*)fontAwesomeIconStringForIconIdentifier:(NSString*)identifier; @end diff --git a/Demo/KoaPullToRefresh/Resources/NSString+FontAwesome.m b/Demo/KoaPullToRefresh/Resources/NSString+FontAwesome.m index f500386..950d7e1 100755 --- a/Demo/KoaPullToRefresh/Resources/NSString+FontAwesome.m +++ b/Demo/KoaPullToRefresh/Resources/NSString+FontAwesome.m @@ -26,299 +26,672 @@ @implementation NSString (FontAwesome) -#pragma mark - public - -/* Returns the correct enum for a font-awesome icon. - * The list of identifiers can be found here: - * http://fortawesome.github.com/Font-awesome/#all-icons */ -+ (FAIcon)fontAwesomeEnumForIconIdentifier:(NSString*)string -{ +#pragma mark - Public API ++ (FAIcon)fontAwesomeEnumForIconIdentifier:(NSString*)string { NSDictionary *enums = [self enumDictionary]; return [enums[string] integerValue]; } -/* Returns the font-awesome character associated to the - * icon enum passed as argument */ -+ (NSString*)fontAwesomeIconStringForEnum:(FAIcon)value -{ - return [self fontAwesomeIcons][value]; ++ (NSString*)fontAwesomeIconStringForEnum:(FAIcon)value { + return [NSString fontAwesomeUnicodeStrings][value]; } -/* Returns the font-awesome character associated to the font-awesome - * identifier. - * http://fortawesome.github.com/Font-awesome/#all-icons */ -+ (NSString*)fontAwesomeIconStringForIconIdentifier:(NSString*)identifier -{ ++ (NSString*)fontAwesomeIconStringForIconIdentifier:(NSString*)identifier { return [self fontAwesomeIconStringForEnum:[self fontAwesomeEnumForIconIdentifier:identifier]]; } -#pragma mark - data initialization -+ (NSArray*)fontAwesomeIcons -{ - static NSArray *fontAwesomeIcons; - if (nil == fontAwesomeIcons) { - fontAwesomeIcons = @[@"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @""]; - } - return fontAwesomeIcons; +#pragma mark - Data Initialization ++ (NSArray *)fontAwesomeUnicodeStrings { + + static NSArray *fontAwesomeUnicodeStrings; + + static dispatch_once_t unicodeStringsOnceToken; + dispatch_once(&unicodeStringsOnceToken, ^{ + + fontAwesomeUnicodeStrings = @[@"\uf000", @"\uf001", @"\uf002", @"\uf003", @"\uf004", @"\uf005", @"\uf006", @"\uf007", @"\uf008", @"\uf009", @"\uf00a", @"\uf00b", @"\uf00c", @"\uf00d", @"\uf00e", @"\uf010", @"\uf011", @"\uf012", @"\uf013", @"\uf014", @"\uf015", @"\uf016", @"\uf017", @"\uf018", @"\uf019", @"\uf01a", @"\uf01b", @"\uf01c", @"\uf01d", @"\uf01e", @"\uf021", @"\uf022", @"\uf023", @"\uf024", @"\uf025", @"\uf026", @"\uf027", @"\uf028", @"\uf029", @"\uf02a", @"\uf02b", @"\uf02c", @"\uf02d", @"\uf02e", @"\uf02f", @"\uf030", @"\uf031", @"\uf032", @"\uf033", @"\uf034", @"\uf035", @"\uf036", @"\uf037", @"\uf038", @"\uf039", @"\uf03a", @"\uf03b", @"\uf03c", @"\uf03d", @"\uf03e", @"\uf040", @"\uf041", @"\uf042", @"\uf043", @"\uf044", @"\uf045", @"\uf046", @"\uf047", @"\uf048", @"\uf049", @"\uf04a", @"\uf04b", @"\uf04c", @"\uf04d", @"\uf04e", @"\uf050", @"\uf051", @"\uf052", @"\uf053", @"\uf054", @"\uf055", @"\uf056", @"\uf057", @"\uf058", @"\uf059", @"\uf05a", @"\uf05b", @"\uf05c", @"\uf05d", @"\uf05e", @"\uf060", @"\uf061", @"\uf062", @"\uf063", @"\uf064", @"\uf065", @"\uf066", @"\uf067", @"\uf068", @"\uf069", @"\uf06a", @"\uf06b", @"\uf06c", @"\uf06d", @"\uf06e", @"\uf070", @"\uf071", @"\uf072", @"\uf073", @"\uf074", @"\uf075", @"\uf076", @"\uf077", @"\uf078", @"\uf079", @"\uf07a", @"\uf07b", @"\uf07c", @"\uf07d", @"\uf07e", @"\uf080", @"\uf081", @"\uf082", @"\uf083", @"\uf084", @"\uf085", @"\uf086", @"\uf087", @"\uf088", @"\uf089", @"\uf08a", @"\uf08b", @"\uf08c", @"\uf08d", @"\uf08e", @"\uf090", @"\uf091", @"\uf092", @"\uf093", @"\uf094", @"\uf095", @"\uf096", @"\uf097", @"\uf098", @"\uf099", @"\uf09a", @"\uf09b", @"\uf09c", @"\uf09d", @"\uf09e", @"\uf0a0", @"\uf0a1", @"\uf0f3", @"\uf0a3", @"\uf0a4", @"\uf0a5", @"\uf0a6", @"\uf0a7", @"\uf0a8", @"\uf0a9", @"\uf0aa", @"\uf0ab", @"\uf0ac", @"\uf0ad", @"\uf0ae", @"\uf0b0", @"\uf0b1", @"\uf0b2", @"\uf0c0", @"\uf0c1", @"\uf0c2", @"\uf0c3", @"\uf0c4", @"\uf0c5", @"\uf0c6", @"\uf0c7", @"\uf0c8", @"\uf0c9", @"\uf0ca", @"\uf0cb", @"\uf0cc", @"\uf0cd", @"\uf0ce", @"\uf0d0", @"\uf0d1", @"\uf0d2", @"\uf0d3", @"\uf0d4", @"\uf0d5", @"\uf0d6", @"\uf0d7", @"\uf0d8", @"\uf0d9", @"\uf0da", @"\uf0db", @"\uf0dc", @"\uf0dd", @"\uf0de", @"\uf0e0", @"\uf0e1", @"\uf0e2", @"\uf0e3", @"\uf0e4", @"\uf0e5", @"\uf0e6", @"\uf0e7", @"\uf0e8", @"\uf0e9", @"\uf0ea", @"\uf0eb", @"\uf0ec", @"\uf0ed", @"\uf0ee", @"\uf0f0", @"\uf0f1", @"\uf0f2", @"\uf0a2", @"\uf0f4", @"\uf0f5", @"\uf0f6", @"\uf0f7", @"\uf0f8", @"\uf0f9", @"\uf0fa", @"\uf0fb", @"\uf0fc", @"\uf0fd", @"\uf0fe", @"\uf100", @"\uf101", @"\uf102", @"\uf103", @"\uf104", @"\uf105", @"\uf106", @"\uf107", @"\uf108", @"\uf109", @"\uf10a", @"\uf10b", @"\uf10c", @"\uf10d", @"\uf10e", @"\uf110", @"\uf111", @"\uf112", @"\uf113", @"\uf114", @"\uf115", @"\uf118", @"\uf119", @"\uf11a", @"\uf11b", @"\uf11c", @"\uf11d", @"\uf11e", @"\uf120", @"\uf121", @"\uf122", @"\uf122", @"\uf123", @"\uf124", @"\uf125", @"\uf126", @"\uf127", @"\uf128", @"\uf129", @"\uf12a", @"\uf12b", @"\uf12c", @"\uf12d", @"\uf12e", @"\uf130", @"\uf131", @"\uf132", @"\uf133", @"\uf134", @"\uf135", @"\uf136", @"\uf137", @"\uf138", @"\uf139", @"\uf13a", @"\uf13b", @"\uf13c", @"\uf13d", @"\uf13e", @"\uf140", @"\uf141", @"\uf142", @"\uf143", @"\uf144", @"\uf145", @"\uf146", @"\uf147", @"\uf148", @"\uf149", @"\uf14a", @"\uf14b", @"\uf14c", @"\uf14d", @"\uf14e", @"\uf150", @"\uf151", @"\uf152", @"\uf153", @"\uf154", @"\uf155", @"\uf156", @"\uf157", @"\uf158", @"\uf159", @"\uf15a", @"\uf15b", @"\uf15c", @"\uf15d", @"\uf15e", @"\uf160", @"\uf161", @"\uf162", @"\uf163", @"\uf164", @"\uf165", @"\uf166", @"\uf167", @"\uf168", @"\uf169", @"\uf16a", @"\uf16b", @"\uf16c", @"\uf16d", @"\uf16e", @"\uf170", @"\uf171", @"\uf172", @"\uf173", @"\uf174", @"\uf175", @"\uf176", @"\uf177", @"\uf178", @"\uf179", @"\uf17a", @"\uf17b", @"\uf17c", @"\uf17d", @"\uf17e", @"\uf180", @"\uf181", @"\uf182", @"\uf183", @"\uf184", @"\uf185", @"\uf186", @"\uf187", @"\uf188", @"\uf189", @"\uf18a", @"\uf18b", @"\uf18c", @"\uf18d", @"\uf18e", @"\uf190", @"\uf191", @"\uf192", @"\uf193", @"\uf194", @"\uf195", @"\uf196", + /* Font Awesome ver 4.10 */ + @"\uf1b9", @"\uf19c", @"\uf1b4", @"\uf1b5", @"\uf1e2", @"\uf1ad", @"\uf1ba", @"\uf1b9", @"\uf1ae", @"\uf1ce", @"\uf1db", @"\uf1cb", @"\uf1b2", @"\uf1b3", @"\uf1c0", @"\uf1a5", @"\uf1bd", @"\uf1a6", @"\uf1a9", @"\uf1d1", @"\uf199", @"\uf1ac", @"\uf1c6", @"\uf1c7", @"\uf1c9", @"\uf1c3", @"\uf1c5", @"\uf1c8", @"\uf1c1", @"\uf1c5", @"\uf1c5", @"\uf1c4", @"\uf1c7", @"\uf1c8", @"\uf1c2", @"\uf1c6", @"\uf1d1", @"\uf1d3", @"\uf1d2", @"\uf1a0", @"\uf19d", @"\uf1d4", @"\uf1dc", @"\uf1da", @"\uf19c", @"\uf1aa", @"\uf1cc", @"\uf1ab", @"\uf1cd", @"\uf1cd", @"\uf1cd", @"\uf19d", @"\uf19b", @"\uf1d8", @"\uf1d9", @"\uf1dd", @"\uf1b0", @"\uf1a7", @"\uf1a8", @"\uf1a7", @"\uf1d6", @"\uf1d0", @"\uf1d0", @"\uf1b8", @"\uf1a1", @"\uf1a2", @"\uf1d8", @"\uf1d9", @"\uf1e0", @"\uf1e1", @"\uf198", @"\uf1de", @"\uf1be", @"\uf197", @"\uf1b1", @"\uf1bc", @"\uf1b6", @"\uf1b7", @"\uf1a4", @"\uf1a3", @"\uf1cd", @"\uf1ba", @"\uf1d5", @"\uf1bb", @"\uf19c", @"\uf1ca", @"\uf1d7", @"\uf1d7", @"\uf19a", @"\uf19e", + /* Font Awesome ver 4.20 */ + @"\uf209", @"\uf1fe", @"\uf1fa", @"\uf1f6", @"\uf1f7", @"\uf206", @"\uf1e5", @"\uf1fd", @"\uf207", @"\uf1ec", @"\uf20a", @"\uf1f3", @"\uf1f2", @"\uf1f1", @"\uf1f4", @"\uf1f5", @"\uf1f0", @"\uf1f9", @"\uf1fb", @"\uf1e3", @"\uf1ee", @"\uf20b", @"\uf208", @"\uf202", @"\uf203", @"\uf201", @"\uf20c", @"\uf1ea", @"\uf1fc", @"\uf1ed", @"\uf200", @"\uf1e6", @"\uf20b", @"\uf20b", @"\uf1e7", @"\uf1e3", @"\uf204", @"\uf205", @"\uf1f8", @"\uf1e4", @"\uf1e8", @"\uf1eb", @"\uf1e9", + /* Font Awesome ver 4.30 */ + @"\uf236", @"\uf20d", @"\uf218", @"\uf217;", @"\uf20e", @"\uf210", @"\uf219", @"\uf230", @"\uf211", @"\uf21e", @"\uf236", @"\uf212", @"\uf222", @"\uf227", @"\uf229", @"\uf22b", @"\uf22a", @"\uf23a", @"\uf223", @"\uf21c", @"\uf22c", @"\uf231", @"\uf213", @"\uf233", @"\uf21a", @"\uf214", @"\uf215", @"\uf216", @"\uf21d", @"\uf239", @"\uf238", @"\uf224", @"\uf225", @"\uf234", @"\uf21b", @"\uf235", @"\uf221", @"\uf226", @"\uf228", @"\uf237", + /* Font Awesome ver 4.40 */ + @"\uf26e", @"\uf270", @"\uf24e", @"\uf244", @"\uf240", @"\uf242", @"\uf243", @"\uf241", @"\uf27e", @"\uf274", @"\uf272", @"\uf271", @"\uf273", @"\uf24c", @"\uf24b", @"\uf268", @"\uf24d", @"\uf27a", @"\uf27b", @"\uf26d", @"\uf25e", @"\uf23e", @"\uf269", @"\uf280", @"\uf22d", @"\uf265", @"\uf260", @"\uf261", @"\uf258", @"\uf256", @"\uf25b", @"\uf25a", @"\uf255", @"\uf257", @"\uf259", @"\uf254", @"\uf253", @"\uf252", @"\uf250", @"\uf251", @"\uf27c", @"\uf246", @"\uf275", @"\uf26b", @"\uf279", @"\uf278", @"\uf276", @"\uf277", @"\uf245", @"\uf247", @"\uf248", @"\uf263", @"\uf264", @"\uf23d", @"\uf26a", @"\uf23c", @"\uf25d", @"\uf267", @"\uf249", @"\uf24a", @"\uf26c", @"\uf25c", @"\uf262", @"\uf27d", @"\uf266", @"\uf23b"]; + + }); + + return fontAwesomeUnicodeStrings; } -+ (NSDictionary*)enumDictionary -{ ++ (NSDictionary *)enumDictionary { + static NSDictionary *enumDictionary; - if (nil == enumDictionary) { + + static dispatch_once_t enumDictionaryOnceToken; + dispatch_once(&enumDictionaryOnceToken, ^{ + NSMutableDictionary *tmp = [[NSMutableDictionary alloc] init]; - tmp[@"icon-glass"] = @(FAIconGlass); - tmp[@"icon-music"] = @(FAIconMusic); - tmp[@"icon-search"] = @(FAIconSearch); - tmp[@"icon-envelope"] = @(FAIconEnvelope); - tmp[@"icon-heart"] = @(FAIconHeart); - tmp[@"icon-star"] = @(FAIconStar); - tmp[@"icon-star-empty"] = @(FAIconStarEmpty); - tmp[@"icon-user"] = @(FAIconUser); - tmp[@"icon-film"] = @(FAIconFilm); - tmp[@"icon-th-large"] = @(FAIconThLarge); - tmp[@"icon-th"] = @(FAIconTh); - tmp[@"icon-th-list"] = @(FAIconThList); - tmp[@"icon-ok"] = @(FAIconOk); - tmp[@"icon-remove"] = @(FAIconRemove); - tmp[@"icon-zoom-in"] = @(FAIconZoomIn); - tmp[@"icon-zoom-out"] = @(FAIconZoomOut); - tmp[@"icon-off"] = @(FAIconOff); - tmp[@"icon-signal"] = @(FAIconSignal); - tmp[@"icon-cog"] = @(FAIconCog); - tmp[@"icon-trash"] = @(FAIconTrash); - tmp[@"icon-home"] = @(FAIconHome); - tmp[@"icon-file"] = @(FAIconFile); - tmp[@"icon-time"] = @(FAIconTime); - tmp[@"icon-road"] = @(FAIconRoad); - tmp[@"icon-download-alt"] = @(FAIconDownloadAlt); - tmp[@"icon-download"] = @(FAIconDownload); - tmp[@"icon-upload"] = @(FAIconUpload); - tmp[@"icon-inbox"] = @(FAIconInbox); - tmp[@"icon-play-circle"] = @(FAIconPlayCircle); - tmp[@"icon-repeat"] = @(FAIconRepeat); - tmp[@"icon-refresh"] = @(FAIconRefresh); - tmp[@"icon-list-alt"] = @(FAIconListAlt); - tmp[@"icon-lock"] = @(FAIconLock); - tmp[@"icon-flag"] = @(FAIconFlag); - tmp[@"icon-headphones"] = @(FAIconHeadphones); - tmp[@"icon-volume-off"] = @(FAIconVolumeOff); - tmp[@"icon-volume-down"] = @(FAIconVolumeDown); - tmp[@"icon-volume-up"] = @(FAIconVolumeUp); - tmp[@"icon-qrcode"] = @(FAIconQrcode); - tmp[@"icon-barcode"] = @(FAIconBarcode); - tmp[@"icon-tag"] = @(FAIconTag); - tmp[@"icon-tags"] = @(FAIconTags); - tmp[@"icon-book"] = @(FAIconBook); - tmp[@"icon-bookmark"] = @(FAIconBookmark); - tmp[@"icon-print"] = @(FAIconPrint); - tmp[@"icon-camera"] = @(FAIconCamera); - tmp[@"icon-font"] = @(FAIconFont); - tmp[@"icon-bold"] = @(FAIconBold); - tmp[@"icon-italic"] = @(FAIconItalic); - tmp[@"icon-text-height"] = @(FAIconTextHeight); - tmp[@"icon-text-width"] = @(FAIconTextWidth); - tmp[@"icon-align-left"] = @(FAIconAlignLeft); - tmp[@"icon-align-center"] = @(FAIconAlignCenter); - tmp[@"icon-align-right"] = @(FAIconAlignRight); - tmp[@"icon-align-justify"] = @(FAIconAlignJustify); - tmp[@"icon-list"] = @(FAIconList); - tmp[@"icon-indent-left"] = @(FAIconIndentLeft); - tmp[@"icon-indent-right"] = @(FAIconIndentRight); - tmp[@"icon-facetime-video"] = @(FAIconFacetimeVideo); - tmp[@"icon-picture"] = @(FAIconPicture); - tmp[@"icon-pencil"] = @(FAIconPencil); - tmp[@"icon-map-marker"] = @(FAIconMapMarker); - tmp[@"icon-adjust"] = @(FAIconAdjust); - tmp[@"icon-tint"] = @(FAIconTint); - tmp[@"icon-edit"] = @(FAIconEdit); - tmp[@"icon-share"] = @(FAIconShare); - tmp[@"icon-check"] = @(FAIconCheck); - tmp[@"icon-move"] = @(FAIconMove); - tmp[@"icon-step-backward"] = @(FAIconStepBackward); - tmp[@"icon-fast-backward"] = @(FAIconFastBackward); - tmp[@"icon-backward"] = @(FAIconBackward); - tmp[@"icon-play"] = @(FAIconPlay); - tmp[@"icon-pause"] = @(FAIconPause); - tmp[@"icon-stop"] = @(FAIconStop); - tmp[@"icon-forward"] = @(FAIconForward); - tmp[@"icon-fast-forward"] = @(FAIconFastForward); - tmp[@"icon-step-forward"] = @(FAIconStepForward); - tmp[@"icon-eject"] = @(FAIconEject); - tmp[@"icon-chevron-left"] = @(FAIconChevronLeft); - tmp[@"icon-chevron-right"] = @(FAIconChevronRight); - tmp[@"icon-plus-sign"] = @(FAIconPlusSign); - tmp[@"icon-minus-sign"] = @(FAIconMinusSign); - tmp[@"icon-remove-sign"] = @(FAIconRemoveSign); - tmp[@"icon-ok-sign"] = @(FAIconOkSign); - tmp[@"icon-question-sign"] = @(FAIconQuestionSign); - tmp[@"icon-info-sign"] = @(FAIconInfoSign); - tmp[@"icon-screenshot"] = @(FAIconScreenshot); - tmp[@"icon-remove-circle"] = @(FAIconRemoveCircle); - tmp[@"icon-ok-circle"] = @(FAIconOkCircle); - tmp[@"icon-ban-circle"] = @(FAIconBanCircle); - tmp[@"icon-arrow-left"] = @(FAIconArrowLeft); - tmp[@"icon-arrow-right"] = @(FAIconArrowRight); - tmp[@"icon-arrow-up"] = @(FAIconArrowUp); - tmp[@"icon-arrow-down"] = @(FAIconArrowDown); - tmp[@"icon-share-alt"] = @(FAIconShareAlt); - tmp[@"icon-resize-full"] = @(FAIconResizeFull); - tmp[@"icon-resize-small"] = @(FAIconResizeSmall); - tmp[@"icon-plus"] = @(FAIconPlus); - tmp[@"icon-minus"] = @(FAIconMinus); - tmp[@"icon-asterisk"] = @(FAIconAsterisk); - tmp[@"icon-exclamation-sign"] = @(FAIconExclamationSign); - tmp[@"icon-gift"] = @(FAIconGift); - tmp[@"icon-leaf"] = @(FAIconLeaf); - tmp[@"icon-fire"] = @(FAIconFire); - tmp[@"icon-eye-open"] = @(FAIconEyeOpen); - tmp[@"icon-eye-close"] = @(FAIconEyeClose); - tmp[@"icon-warning-sign"] = @(FAIconWarningSign); - tmp[@"icon-plane"] = @(FAIconPlane); - tmp[@"icon-calendar"] = @(FAIconCalendar); - tmp[@"icon-random"] = @(FAIconRandom); - tmp[@"icon-comment"] = @(FAIconComment); - tmp[@"icon-magnet"] = @(FAIconMagnet); - tmp[@"icon-chevron-up"] = @(FAIconChevronUp); - tmp[@"icon-chevron-down"] = @(FAIconChevronDown); - tmp[@"icon-retweet"] = @(FAIconRetweet); - tmp[@"icon-shopping-cart"] = @(FAIconShoppingCart); - tmp[@"icon-folder-close"] = @(FAIconFolderClose); - tmp[@"icon-folder-open"] = @(FAIconFolderOpen); - tmp[@"icon-resize-vertical"] = @(FAIconResizeVertical); - tmp[@"icon-resize-horizontal"] = @(FAIconResizeHorizontal); - tmp[@"icon-bar-chart"] = @(FAIconBarChart); - tmp[@"icon-twitter-sign"] = @(FAIconTwitterSign); - tmp[@"icon-facebook-sign"] = @(FAIconFacebookSign); - tmp[@"icon-camera-retro"] = @(FAIconCameraRetro); - tmp[@"icon-key"] = @(FAIconKey); - tmp[@"icon-cogs"] = @(FAIconCogs); - tmp[@"icon-comments"] = @(FAIconComments); - tmp[@"icon-thumbs-up"] = @(FAIconThumbsUp); - tmp[@"icon-thumbs-down"] = @(FAIconThumbsDown); - tmp[@"icon-star-half"] = @(FAIconStarHalf); - tmp[@"icon-heart-empty"] = @(FAIconHeartEmpty); - tmp[@"icon-signout"] = @(FAIconSignout); - tmp[@"icon-linkedin-sign"] = @(FAIconLinkedinSign); - tmp[@"icon-pushpin"] = @(FAIconPushpin); - tmp[@"icon-external-link"] = @(FAIconExternalLink); - tmp[@"icon-signin"] = @(FAIconSignin); - tmp[@"icon-trophy"] = @(FAIconTrophy); - tmp[@"icon-github-sign"] = @(FAIconGithubSign); - tmp[@"icon-upload-alt"] = @(FAIconUploadAlt); - tmp[@"icon-lemon"] = @(FAIconLemon); - tmp[@"icon-phone"] = @(FAIconPhone); - tmp[@"icon-check-empty"] = @(FAIconCheckEmpty); - tmp[@"icon-bookmark-empty"] = @(FAIconBookmarkEmpty); - tmp[@"icon-phone-sign"] = @(FAIconPhoneSign); - tmp[@"icon-twitter"] = @(FAIconTwitter); - tmp[@"icon-facebook"] = @(FAIconFacebook); - tmp[@"icon-github"] = @(FAIconGithub); - tmp[@"icon-unlock"] = @(FAIconUnlock); - tmp[@"icon-credit-card"] = @(FAIconCreditCard); - tmp[@"icon-rss"] = @(FAIconRss); - tmp[@"icon-hdd"] = @(FAIconHdd); - tmp[@"icon-bullhorn"] = @(FAIconBullhorn); - tmp[@"icon-bell"] = @(FAIconBell); - tmp[@"icon-certificate"] = @(FAIconCertificate); - tmp[@"icon-hand-right"] = @(FAIconHandRight); - tmp[@"icon-hand-left"] = @(FAIconHandLeft); - tmp[@"icon-hand-up"] = @(FAIconHandUp); - tmp[@"icon-hand-down"] = @(FAIconHandDown); - tmp[@"icon-circle-arrow-left"] = @(FAIconCircleArrowLeft); - tmp[@"icon-circle-arrow-right"] = @(FAIconCircleArrowRight); - tmp[@"icon-circle-arrow-up"] = @(FAIconCircleArrowUp); - tmp[@"icon-circle-arrow-down"] = @(FAIconCircleArrowDown); - tmp[@"icon-globe"] = @(FAIconGlobe); - tmp[@"icon-wrench"] = @(FAIconWrench); - tmp[@"icon-tasks"] = @(FAIconTasks); - tmp[@"icon-filter"] = @(FAIconFilter); - tmp[@"icon-briefcase"] = @(FAIconBriefcase); - tmp[@"icon-fullscreen"] = @(FAIconFullscreen); - tmp[@"icon-group"] = @(FAIconGroup); - tmp[@"icon-link"] = @(FAIconLink); - tmp[@"icon-cloud"] = @(FAIconCloud); - tmp[@"icon-beaker"] = @(FAIconBeaker); - tmp[@"icon-cut"] = @(FAIconCut); - tmp[@"icon-copy"] = @(FAIconCopy); - tmp[@"icon-paper-clip"] = @(FAIconPaperClip); - tmp[@"icon-save"] = @(FAIconSave); - tmp[@"icon-sign-blank"] = @(FAIconSignBlank); - tmp[@"icon-reorder"] = @(FAIconReorder); - tmp[@"icon-list-ul"] = @(FAIconListUl); - tmp[@"icon-list-ol"] = @(FAIconListOl); - tmp[@"icon-strikethrough"] = @(FAIconStrikethrough); - tmp[@"icon-underline"] = @(FAIconUnderline); - tmp[@"icon-table"] = @(FAIconTable); - tmp[@"icon-magic"] = @(FAIconMagic); - tmp[@"icon-truck"] = @(FAIconTruck); - tmp[@"icon-pinterest"] = @(FAIconPinterest); - tmp[@"icon-pinterest-sign"] = @(FAIconPinterestSign); - tmp[@"icon-google-plus-sign"] = @(FAIconGooglePlusSign); - tmp[@"icon-google-plus"] = @(FAIconGooglePlus); - tmp[@"icon-money"] = @(FAIconMoney); - tmp[@"icon-caret-down"] = @(FAIconCaretDown); - tmp[@"icon-caret-up"] = @(FAIconCaretUp); - tmp[@"icon-caret-left"] = @(FAIconCaretLeft); - tmp[@"icon-caret-right"] = @(FAIconCaretRight); - tmp[@"icon-columns"] = @(FAIconColumns); - tmp[@"icon-sort"] = @(FAIconSort); - tmp[@"icon-sort-down"] = @(FAIconSortDown); - tmp[@"icon-sort-up"] = @(FAIconSortUp); - tmp[@"icon-envelope-alt"] = @(FAIconEnvelopeAlt); - tmp[@"icon-linkedin"] = @(FAIconLinkedin); - tmp[@"icon-undo"] = @(FAIconUndo); - tmp[@"icon-legal"] = @(FAIconLegal); - tmp[@"icon-dashboard"] = @(FAIconDashboard); - tmp[@"icon-comment-alt"] = @(FAIconCommentAlt); - tmp[@"icon-comments-alt"] = @(FAIconCommentsAlt); - tmp[@"icon-bolt"] = @(FAIconBolt); - tmp[@"icon-sitemap"] = @(FAIconSitemap); - tmp[@"icon-umbrella"] = @(FAIconUmbrella); - tmp[@"icon-paste"] = @(FAIconPaste); - tmp[@"icon-user-md"] = @(FAIconUserMd); - tmp[@"icon-stethoscope"] = @(FAIconStethoscope); - tmp[@"icon-building"] = @(FAIconBuilding); - tmp[@"icon-hospital"] = @(FAIconHospital); - tmp[@"icon-ambulance"] = @(FAIconAmbulance); - tmp[@"icon-medkit"] = @(FAIconMedkit); - tmp[@"icon-h-sign"] = @(FAIconHSign); - tmp[@"icon-plus-sign-alt"] = @(FAIconPlusSignAlt); - tmp[@"icon-spinner"] = @(FAIconSpinner); - tmp[@"icon-cloud-download"] = @(FAIconCloudDownload); - tmp[@"icon-cloud-upload"] = @(FAIconCloudUpload); - tmp[@"icon-lightbulb"] = @(FAIconLightbulb); - tmp[@"icon-exchange"] = @(FAIconExchange); - tmp[@"icon-bell-alt"] = @(FAIconBellAlt); - tmp[@"icon-file-alt"] = @(FAIconFileAlt); - tmp[@"icon-beer"] = @(FAIconBeer); - tmp[@"icon-coffee"] = @(FAIconCoffee); - tmp[@"icon-food"] = @(FAIconFood); - tmp[@"icon-fighter-jet"] = @(FAIconFighterJet); - tmp[@"icon-angle-left"] = @(FAIconAngleLeft); - tmp[@"icon-angle-right"] = @(FAIconAngleRight); - tmp[@"icon-angle-up"] = @(FAIconAngleUp); - tmp[@"icon-angle-down"] = @(FAIconAngleDown); - tmp[@"icon-double-angle-left"] = @(FAIconDoubleAngleLeft); - tmp[@"icon-double-angle-right"] = @(FAIconDoubleAngleRight); - tmp[@"icon-double-angle-up"] = @(FAIconDoubleAngleUp); - tmp[@"icon-double-angle-down"] = @(FAIconDoubleAngleDown); - tmp[@"icon-circle-blank"] = @(FAIconCircleBlank); - tmp[@"icon-circle"] = @(FAIconCircle); - tmp[@"icon-desktop"] = @(FAIconDesktop); - tmp[@"icon-laptop"] = @(FAIconLaptop); - tmp[@"icon-tablet"] = @(FAIconTablet); - tmp[@"icon-mobile-phone"] = @(FAIconMobilePhone); - tmp[@"icon-quote-left"] = @(FAIconQuoteLeft); - tmp[@"icon-quote-right"] = @(FAIconQuoteRight); - tmp[@"icon-reply"] = @(FAIconReply); - tmp[@"icon-github-alt"] = @(FAIconGithubAlt); - tmp[@"icon-close-alt"] = @(FAIconFolderCloseAlt); - tmp[@"icon-folder-open-alt"] = @(FAIconFolderOpenAlt); - tmp[@"icon-suitcase"] = @(FAIconSuitcase); + + tmp[@"fa-glass"] = @(FAGlass); + tmp[@"fa-music"] = @(FAMusic); + tmp[@"fa-search"] = @(FASearch); + tmp[@"fa-envelope-o"] = @(FAEnvelopeO); + tmp[@"fa-heart"] = @(FAHeart); + tmp[@"fa-star"] = @(FAStar); + tmp[@"fa-star-o"] = @(FAStarO); + tmp[@"fa-user"] = @(FAUser); + tmp[@"fa-film"] = @(FAFilm); + tmp[@"fa-th-large"] = @(FAThLarge); + tmp[@"fa-th"] = @(FATh); + tmp[@"fa-th-list"] = @(FAThList); + tmp[@"fa-check"] = @(FACheck); + tmp[@"fa-times"] = @(FATimes); + tmp[@"fa-search-plus"] = @(FASearchPlus); + tmp[@"fa-search-minus"] = @(FASearchMinus); + tmp[@"fa-power-off"] = @(FAPowerOff); + tmp[@"fa-signal"] = @(FASignal); + tmp[@"fa-cog"] = @(FACog); + tmp[@"fa-trash-o"] = @(FATrashO); + tmp[@"fa-home"] = @(FAHome); + tmp[@"fa-file-o"] = @(FAFileO); + tmp[@"fa-clock-o"] = @(FAClockO); + tmp[@"fa-road"] = @(FARoad); + tmp[@"fa-download"] = @(FADownload); + tmp[@"fa-arrow-circle-o-down"] = @(FAArrowCircleODown); + tmp[@"fa-arrow-circle-o-up"] = @(FAArrowCircleOUp); + tmp[@"fa-inbox"] = @(FAInbox); + tmp[@"fa-play-circle-o"] = @(FAPlayCircleO); + tmp[@"fa-repeat"] = @(FARepeat); + tmp[@"fa-refresh"] = @(FARefresh); + tmp[@"fa-list-alt"] = @(FAListAlt); + tmp[@"fa-lock"] = @(FALock); + tmp[@"fa-flag"] = @(FAFlag); + tmp[@"fa-headphones"] = @(FAHeadphones); + tmp[@"fa-volume-off"] = @(FAVolumeOff); + tmp[@"fa-volume-down"] = @(FAVolumeDown); + tmp[@"fa-volume-up"] = @(FAVolumeUp); + tmp[@"fa-qrcode"] = @(FAQrcode); + tmp[@"fa-barcode"] = @(FABarcode); + tmp[@"fa-tag"] = @(FATag); + tmp[@"fa-tags"] = @(FATags); + tmp[@"fa-book"] = @(FABook); + tmp[@"fa-bookmark"] = @(FABookmark); + tmp[@"fa-print"] = @(FAPrint); + tmp[@"fa-camera"] = @(FACamera); + tmp[@"fa-font"] = @(FAFont); + tmp[@"fa-bold"] = @(FABold); + tmp[@"fa-italic"] = @(FAItalic); + tmp[@"fa-text-height"] = @(FATextHeight); + tmp[@"fa-text-width"] = @(FATextWidth); + tmp[@"fa-align-left"] = @(FAAlignLeft); + tmp[@"fa-align-center"] = @(FAAlignCenter); + tmp[@"fa-align-right"] = @(FAAlignRight); + tmp[@"fa-align-justify"] = @(FAAlignJustify); + tmp[@"fa-list"] = @(FAList); + tmp[@"fa-outdent"] = @(FAOutdent); + tmp[@"fa-indent"] = @(FAIndent); + tmp[@"fa-video-camera"] = @(FAVideoCamera); + tmp[@"fa-picture-o"] = @(FAPictureO); + tmp[@"fa-pencil"] = @(FAPencil); + tmp[@"fa-map-marker"] = @(FAMapMarker); + tmp[@"fa-adjust"] = @(FAAdjust); + tmp[@"fa-tint"] = @(FATint); + tmp[@"fa-pencil-square-o"] = @(FAPencilSquareO); + tmp[@"fa-share-square-o"] = @(FAShareSquareO); + tmp[@"fa-check-square-o"] = @(FACheckSquareO); + tmp[@"fa-arrows"] = @(FAArrows); + tmp[@"fa-step-backward"] = @(FAStepBackward); + tmp[@"fa-fast-backward"] = @(FAFastBackward); + tmp[@"fa-backward"] = @(FABackward); + tmp[@"fa-play"] = @(FAPlay); + tmp[@"fa-pause"] = @(FAPause); + tmp[@"fa-stop"] = @(FAStop); + tmp[@"fa-forward"] = @(FAForward); + tmp[@"fa-fast-forward"] = @(FAFastForward); + tmp[@"fa-step-forward"] = @(FAStepForward); + tmp[@"fa-eject"] = @(FAEject); + tmp[@"fa-chevron-left"] = @(FAChevronLeft); + tmp[@"fa-chevron-right"] = @(FAChevronRight); + tmp[@"fa-plus-circle"] = @(FAPlusCircle); + tmp[@"fa-minus-circle"] = @(FAMinusCircle); + tmp[@"fa-times-circle"] = @(FATimesCircle); + tmp[@"fa-check-circle"] = @(FACheckCircle); + tmp[@"fa-question-circle"] = @(FAQuestionCircle); + tmp[@"fa-info-circle"] = @(FAInfoCircle); + tmp[@"fa-crosshairs"] = @(FACrosshairs); + tmp[@"fa-times-circle-o"] = @(FATimesCircleO); + tmp[@"fa-check-circle-o"] = @(FACheckCircleO); + tmp[@"fa-ban"] = @(FABan); + tmp[@"fa-arrow-left"] = @(FAArrowLeft); + tmp[@"fa-arrow-right"] = @(FAArrowRight); + tmp[@"fa-arrow-up"] = @(FAArrowUp); + tmp[@"fa-arrow-down"] = @(FAArrowDown); + tmp[@"fa-share"] = @(FAShare); + tmp[@"fa-expand"] = @(FAExpand); + tmp[@"fa-compress"] = @(FACompress); + tmp[@"fa-plus"] = @(FAPlus); + tmp[@"fa-minus"] = @(FAMinus); + tmp[@"fa-asterisk"] = @(FAAsterisk); + tmp[@"fa-exclamation-circle"] = @(FAExclamationCircle); + tmp[@"fa-gift"] = @(FAGift); + tmp[@"fa-leaf"] = @(FALeaf); + tmp[@"fa-fire"] = @(FAFire); + tmp[@"fa-eye"] = @(FAEye); + tmp[@"fa-eye-slash"] = @(FAEyeSlash); + tmp[@"fa-exclamation-triangle"] = @(FAExclamationTriangle); + tmp[@"fa-plane"] = @(FAPlane); + tmp[@"fa-calendar"] = @(FACalendar); + tmp[@"fa-random"] = @(FARandom); + tmp[@"fa-comment"] = @(FAComment); + tmp[@"fa-magnet"] = @(FAMagnet); + tmp[@"fa-chevron-up"] = @(FAChevronUp); + tmp[@"fa-chevron-down"] = @(FAChevronDown); + tmp[@"fa-retweet"] = @(FARetweet); + tmp[@"fa-shopping-cart"] = @(FAShoppingCart); + tmp[@"fa-folder"] = @(FAFolder); + tmp[@"fa-folder-open"] = @(FAFolderOpen); + tmp[@"fa-arrows-v"] = @(FAArrowsV); + tmp[@"fa-arrows-h"] = @(FAArrowsH); + tmp[@"fa-bar-chart-o"] = @(FABarChartO); + tmp[@"fa-twitter-square"] = @(FATwitterSquare); + tmp[@"fa-facebook-square"] = @(FAFacebookSquare); + tmp[@"fa-camera-retro"] = @(FACameraRetro); + tmp[@"fa-key"] = @(FAKey); + tmp[@"fa-cogs"] = @(FACogs); + tmp[@"fa-comments"] = @(FAComments); + tmp[@"fa-thumbs-o-up"] = @(FAThumbsOUp); + tmp[@"fa-thumbs-o-down"] = @(FAThumbsODown); + tmp[@"fa-star-half"] = @(FAStarHalf); + tmp[@"fa-heart-o"] = @(FAHeartO); + tmp[@"fa-sign-out"] = @(FASignOut); + tmp[@"fa-linkedin-square"] = @(FALinkedinSquare); + tmp[@"fa-thumb-tack"] = @(FAThumbTack); + tmp[@"fa-external-link"] = @(FAExternalLink); + tmp[@"fa-sign-in"] = @(FASignIn); + tmp[@"fa-trophy"] = @(FATrophy); + tmp[@"fa-github-square"] = @(FAGithubSquare); + tmp[@"fa-upload"] = @(FAUpload); + tmp[@"fa-lemon-o"] = @(FALemonO); + tmp[@"fa-phone"] = @(FAPhone); + tmp[@"fa-square-o"] = @(FASquareO); + tmp[@"fa-bookmark-o"] = @(FABookmarkO); + tmp[@"fa-phone-square"] = @(FAPhoneSquare); + tmp[@"fa-twitter"] = @(FATwitter); + tmp[@"fa-facebook"] = @(FAFacebook); + tmp[@"fa-github"] = @(FAGithub); + tmp[@"fa-unlock"] = @(FAUnlock); + tmp[@"fa-credit-card"] = @(FACreditCard); + tmp[@"fa-rss"] = @(FARss); + tmp[@"fa-hdd-o"] = @(FAHddO); + tmp[@"fa-bullhorn"] = @(FABullhorn); + tmp[@"fa-bell"] = @(FABell); + tmp[@"fa-certificate"] = @(FACertificate); + tmp[@"fa-hand-o-right"] = @(FAHandORight); + tmp[@"fa-hand-o-left"] = @(FAHandOLeft); + tmp[@"fa-hand-o-up"] = @(FAHandOUp); + tmp[@"fa-hand-o-down"] = @(FAHandODown); + tmp[@"fa-arrow-circle-left"] = @(FAArrowCircleLeft); + tmp[@"fa-arrow-circle-right"] = @(FAArrowCircleRight); + tmp[@"fa-arrow-circle-up"] = @(FAArrowCircleUp); + tmp[@"fa-arrow-circle-down"] = @(FAArrowCircleDown); + tmp[@"fa-globe"] = @(FAGlobe); + tmp[@"fa-wrench"] = @(FAWrench); + tmp[@"fa-tasks"] = @(FATasks); + tmp[@"fa-filter"] = @(FAFilter); + tmp[@"fa-briefcase"] = @(FABriefcase); + tmp[@"fa-arrows-alt"] = @(FAArrowsAlt); + tmp[@"fa-users"] = @(FAUsers); + tmp[@"fa-link"] = @(FALink); + tmp[@"fa-cloud"] = @(FACloud); + tmp[@"fa-flask"] = @(FAFlask); + tmp[@"fa-scissors"] = @(FAScissors); + tmp[@"fa-files-o"] = @(FAFilesO); + tmp[@"fa-paperclip"] = @(FAPaperclip); + tmp[@"fa-floppy-o"] = @(FAFloppyO); + tmp[@"fa-square"] = @(FASquare); + tmp[@"fa-bars"] = @(FABars); + tmp[@"fa-list-ul"] = @(FAListUl); + tmp[@"fa-list-ol"] = @(FAListOl); + tmp[@"fa-strikethrough"] = @(FAStrikethrough); + tmp[@"fa-underline"] = @(FAUnderline); + tmp[@"fa-table"] = @(FATable); + tmp[@"fa-magic"] = @(FAMagic); + tmp[@"fa-truck"] = @(FATruck); + tmp[@"fa-pinterest"] = @(FAPinterest); + tmp[@"fa-pinterest-square"] = @(FAPinterestSquare); + tmp[@"fa-google-plus-square"] = @(FAGooglePlusSquare); + tmp[@"fa-google-plus"] = @(FAGooglePlus); + tmp[@"fa-money"] = @(FAMoney); + tmp[@"fa-caret-down"] = @(FACaretDown); + tmp[@"fa-caret-up"] = @(FACaretUp); + tmp[@"fa-caret-left"] = @(FACaretLeft); + tmp[@"fa-caret-right"] = @(FACaretRight); + tmp[@"fa-columns"] = @(FAColumns); + tmp[@"fa-sort"] = @(FASort); + tmp[@"fa-sort-asc"] = @(FASortAsc); + tmp[@"fa-sort-desc"] = @(FASortDesc); + tmp[@"fa-envelope"] = @(FAEnvelope); + tmp[@"fa-linkedin"] = @(FALinkedin); + tmp[@"fa-undo"] = @(FAUndo); + tmp[@"fa-gavel"] = @(FAGavel); + tmp[@"fa-tachometer"] = @(FATachometer); + tmp[@"fa-comment-o"] = @(FACommentO); + tmp[@"fa-comments-o"] = @(FACommentsO); + tmp[@"fa-bolt"] = @(FABolt); + tmp[@"fa-sitemap"] = @(FASitemap); + tmp[@"fa-umbrella"] = @(FAUmbrella); + tmp[@"fa-clipboard"] = @(FAClipboard); + tmp[@"fa-lightbulb-o"] = @(FALightbulbO); + tmp[@"fa-exchange"] = @(FAExchange); + tmp[@"fa-cloud-download"] = @(FACloudDownload); + tmp[@"fa-cloud-upload"] = @(FACloudUpload); + tmp[@"fa-user-md"] = @(FAUserMd); + tmp[@"fa-stethoscope"] = @(FAStethoscope); + tmp[@"fa-suitcase"] = @(FASuitcase); + tmp[@"fa-bell-o"] = @(FABellO); + tmp[@"fa-coffee"] = @(FACoffee); + tmp[@"fa-cutlery"] = @(FACutlery); + tmp[@"fa-file-text-o"] = @(FAFileTextO); + tmp[@"fa-building-o"] = @(FABuildingO); + tmp[@"fa-hospital-o"] = @(FAHospitalO); + tmp[@"fa-ambulance"] = @(FAAmbulance); + tmp[@"fa-medkit"] = @(FAMedkit); + tmp[@"fa-fighter-jet"] = @(FAFighterJet); + tmp[@"fa-beer"] = @(FABeer); + tmp[@"fa-h-square"] = @(FAHSquare); + tmp[@"fa-plus-square"] = @(FAPlusSquare); + tmp[@"fa-angle-double-left"] = @(FAAngleDoubleLeft); + tmp[@"fa-angle-double-right"] = @(FAAngleDoubleRight); + tmp[@"fa-angle-double-up"] = @(FAAngleDoubleUp); + tmp[@"fa-angle-double-down"] = @(FAAngleDoubleDown); + tmp[@"fa-angle-left"] = @(FAAngleLeft); + tmp[@"fa-angle-right"] = @(FAAngleRight); + tmp[@"fa-angle-up"] = @(FAAngleUp); + tmp[@"fa-angle-down"] = @(FAAngleDown); + tmp[@"fa-desktop"] = @(FADesktop); + tmp[@"fa-laptop"] = @(FALaptop); + tmp[@"fa-tablet"] = @(FATablet); + tmp[@"fa-mobile"] = @(FAMobile); + tmp[@"fa-circle-o"] = @(FACircleO); + tmp[@"fa-quote-left"] = @(FAQuoteLeft); + tmp[@"fa-quote-right"] = @(FAQuoteRight); + tmp[@"fa-spinner"] = @(FASpinner); + tmp[@"fa-circle"] = @(FACircle); + tmp[@"fa-reply"] = @(FAReply); + tmp[@"fa-github-alt"] = @(FAGithubAlt); + tmp[@"fa-folder-o"] = @(FAFolderO); + tmp[@"fa-folder-open-o"] = @(FAFolderOpenO); + tmp[@"fa-smile-o"] = @(FASmileO); + tmp[@"fa-frown-o"] = @(FAFrownO); + tmp[@"fa-meh-o"] = @(FAMehO); + tmp[@"fa-gamepad"] = @(FAGamepad); + tmp[@"fa-keyboard-o"] = @(FAKeyboardO); + tmp[@"fa-flag-o"] = @(FAFlagO); + tmp[@"fa-flag-checkered"] = @(FAFlagCheckered); + tmp[@"fa-terminal"] = @(FATerminal); + tmp[@"fa-code"] = @(FACode); + tmp[@"fa-reply-all"] = @(FAReplyAll); + tmp[@"fa-mail-reply-all"] = @(FAMailReplyAll); + tmp[@"fa-star-half-o"] = @(FAStarHalfO); + tmp[@"fa-location-arrow"] = @(FALocationArrow); + tmp[@"fa-crop"] = @(FACrop); + tmp[@"fa-code-fork"] = @(FACodeFork); + tmp[@"fa-chain-broken"] = @(FAChainBroken); + tmp[@"fa-question"] = @(FAQuestion); + tmp[@"fa-info"] = @(FAInfo); + tmp[@"fa-exclamation"] = @(FAExclamation); + tmp[@"fa-superscript"] = @(FASuperscript); + tmp[@"fa-subscript"] = @(FASubscript); + tmp[@"fa-eraser"] = @(FAEraser); + tmp[@"fa-puzzle-piece"] = @(FAPuzzlePiece); + tmp[@"fa-microphone"] = @(FAMicrophone); + tmp[@"fa-microphone-slash"] = @(FAMicrophoneSlash); + tmp[@"fa-shield"] = @(FAShield); + tmp[@"fa-calendar-o"] = @(FACalendarO); + tmp[@"fa-fire-extinguisher"] = @(FAFireExtinguisher); + tmp[@"fa-rocket"] = @(FARocket); + tmp[@"fa-maxcdn"] = @(FAMaxcdn); + tmp[@"fa-chevron-circle-left"] = @(FAChevronCircleLeft); + tmp[@"fa-chevron-circle-right"] = @(FAChevronCircleRight); + tmp[@"fa-chevron-circle-up"] = @(FAChevronCircleUp); + tmp[@"fa-chevron-circle-down"] = @(FAChevronCircleDown); + tmp[@"fa-html5"] = @(FAHtml5); + tmp[@"fa-css3"] = @(FACss3); + tmp[@"fa-anchor"] = @(FAAnchor); + tmp[@"fa-unlock-alt"] = @(FAUnlockAlt); + tmp[@"fa-bullseye"] = @(FABullseye); + tmp[@"fa-ellipsis-h"] = @(FAEllipsisH); + tmp[@"fa-ellipsis-v"] = @(FAEllipsisV); + tmp[@"fa-rss-square"] = @(FARssSquare); + tmp[@"fa-play-circle"] = @(FAPlayCircle); + tmp[@"fa-ticket"] = @(FATicket); + tmp[@"fa-minus-square"] = @(FAMinusSquare); + tmp[@"fa-minus-square-o"] = @(FAMinusSquareO); + tmp[@"fa-level-up"] = @(FALevelUp); + tmp[@"fa-level-down"] = @(FALevelDown); + tmp[@"fa-check-square"] = @(FACheckSquare); + tmp[@"fa-pencil-square"] = @(FAPencilSquare); + tmp[@"fa-external-link-square"] = @(FAExternalLinkSquare); + tmp[@"fa-share-square"] = @(FAShareSquare); + tmp[@"fa-compass"] = @(FACompass); + tmp[@"fa-caret-square-o-down"] = @(FACaretSquareODown); + tmp[@"fa-caret-square-o-up"] = @(FACaretSquareOUp); + tmp[@"fa-caret-square-o-right"] = @(FACaretSquareORight); + tmp[@"fa-eur"] = @(FAEur); + tmp[@"fa-gbp"] = @(FAGbp); + tmp[@"fa-usd"] = @(FAUsd); + tmp[@"fa-inr"] = @(FAInr); + tmp[@"fa-jpy"] = @(FAJpy); + tmp[@"fa-rub"] = @(FARub); + tmp[@"fa-krw"] = @(FAKrw); + tmp[@"fa-btc"] = @(FABtc); + tmp[@"fa-file"] = @(FAFile); + tmp[@"fa-file-text"] = @(FAFileText); + tmp[@"fa-sort-alpha-asc"] = @(FASortAlphaAsc); + tmp[@"fa-sort-alpha-desc"] = @(FASortAlphaDesc); + tmp[@"fa-sort-amount-asc"] = @(FASortAmountAsc); + tmp[@"fa-sort-amount-desc"] = @(FASortAmountDesc); + tmp[@"fa-sort-numeric-asc"] = @(FASortNumericAsc); + tmp[@"fa-sort-numeric-desc"] = @(FASortNumericDesc); + tmp[@"fa-thumbs-up"] = @(FAThumbsUp); + tmp[@"fa-thumbs-down"] = @(FAThumbsDown); + tmp[@"fa-youtube-square"] = @(FAYoutubeSquare); + tmp[@"fa-youtube"] = @(FAYoutube); + tmp[@"fa-xing"] = @(FAXing); + tmp[@"fa-xing-square"] = @(FAXingSquare); + tmp[@"fa-youtube-play"] = @(FAYoutubePlay); + tmp[@"fa-dropbox"] = @(FADropbox); + tmp[@"fa-stack-overflow"] = @(FAStackOverflow); + tmp[@"fa-instagram"] = @(FAInstagram); + tmp[@"fa-flickr"] = @(FAFlickr); + tmp[@"fa-adn"] = @(FAAdn); + tmp[@"fa-bitbucket"] = @(FABitbucket); + tmp[@"fa-bitbucket-square"] = @(FABitbucketSquare); + tmp[@"fa-tumblr"] = @(FATumblr); + tmp[@"fa-tumblr-square"] = @(FATumblrSquare); + tmp[@"fa-long-arrow-down"] = @(FALongArrowDown); + tmp[@"fa-long-arrow-up"] = @(FALongArrowUp); + tmp[@"fa-long-arrow-left"] = @(FALongArrowLeft); + tmp[@"fa-long-arrow-right"] = @(FALongArrowRight); + tmp[@"fa-apple"] = @(FAApple); + tmp[@"fa-windows"] = @(FAWindows); + tmp[@"fa-android"] = @(FAAndroid); + tmp[@"fa-linux"] = @(FALinux); + tmp[@"fa-dribbble"] = @(FADribbble); + tmp[@"fa-skype"] = @(FASkype); + tmp[@"fa-foursquare"] = @(FAFoursquare); + tmp[@"fa-trello"] = @(FATrello); + tmp[@"fa-female"] = @(FAFemale); + tmp[@"fa-male"] = @(FAMale); + tmp[@"fa-gittip"] = @(FAGittip); + tmp[@"fa-sun-o"] = @(FASunO); + tmp[@"fa-moon-o"] = @(FAMoonO); + tmp[@"fa-archive"] = @(FAArchive); + tmp[@"fa-bug"] = @(FABug); + tmp[@"fa-vk"] = @(FAVk); + tmp[@"fa-weibo"] = @(FAWeibo); + tmp[@"fa-renren"] = @(FARenren); + tmp[@"fa-pagelines"] = @(FAPagelines); + tmp[@"fa-stack-exchange"] = @(FAStackExchange); + tmp[@"fa-arrow-circle-o-right"] = @(FAArrowCircleORight); + tmp[@"fa-arrow-circle-o-left"] = @(FAArrowCircleOLeft); + tmp[@"fa-caret-square-o-left"] = @(FACaretSquareOLeft); + tmp[@"fa-dot-circle-o"] = @(FADotCircleO); + tmp[@"fa-wheelchair"] = @(FAWheelchair); + tmp[@"fa-vimeo-square"] = @(FAVimeoSquare); + tmp[@"fa-try"] = @(FATry); + tmp[@"fa-plus-square-o"] = @(FAPlusSquareO); + + /* FontAwesome ver 4.1.0 */ + tmp[@"fa-automobile"] = @(FAautomobile); + tmp[@"fa-bank"] = @(FAbank); + tmp[@"fa-behance"] = @(FAbehance); + tmp[@"fa-behance-square"] = @(FAbehanceSquare); + tmp[@"fa-bomb"] = @(FAbomb); + tmp[@"fa-building"] = @(FAbuilding); + tmp[@"fa-cab"] = @(FAcab); + tmp[@"fa-car"] = @(FAcar); + tmp[@"fa-child"] = @(FAchild); + tmp[@"fa-circle-o-notch"] = @(FAcircleONotch); + tmp[@"fa-circle-thin"] = @(FAcircleThin); + tmp[@"fa-codepen"] = @(FAcodepen); + tmp[@"fa-cube"] = @(FAcube); + tmp[@"fa-cubes"] = @(FAcubes); + tmp[@"fa-database"] = @(FAdatabase); + tmp[@"fa-delicious"] = @(FAdelicious); + tmp[@"fa-deviantart"] = @(FAdeviantart); + tmp[@"fa-digg"] = @(FAdigg); + tmp[@"fa-drupal"] = @(FAdrupal); + tmp[@"fa-empire"] = @(FAempire); + tmp[@"fa-envelope-square"] = @(FAenvelopeSquare); + tmp[@"fa-fax"] = @(FAfax); + tmp[@"fa-file-archive-o"] = @(FAfileArchiveO); + tmp[@"fa-file-audio-o"] = @(FAfileAudioO); + tmp[@"fa-file-code-o"] = @(FAfileCodeO); + tmp[@"fa-file-excel-o"] = @(FAfileExcelO); + tmp[@"fa-file-image-o"] = @(FAfileImageO); + tmp[@"fa-file-movie-o"] = @(FAfileMovieO); + tmp[@"fa-file-pdf-o"] = @(FAfilePdfO); + tmp[@"fa-file-photo-o"] = @(FAfilePhotoO); + tmp[@"fa-file-picture-o"] = @(FAfilePictureO); + tmp[@"fa-file-powerpoint-o"] = @(FAfilePowerpointO); + tmp[@"fa-file-sound-o"] = @(FAfileSoundO); + tmp[@"fa-file-video-o"] = @(FAfileVideoO); + tmp[@"fa-file-word-o"] = @(FAfileWordO); + tmp[@"fa-file-zip-o"] = @(FAfileZipO); + tmp[@"fa-ge"] = @(FAge); + tmp[@"fa-git"] = @(FAgit); + tmp[@"fa-git-square"] = @(FAgitSquare); + tmp[@"fa-google"] = @(FAgoogle); + tmp[@"fa-graduation-cap"] = @(FAgraduationCap); + tmp[@"fa-hacker-news"] = @(FAhackerNews); + tmp[@"fa-header"] = @(FAheader); + tmp[@"fa-history"] = @(FAhistory); + tmp[@"fa-institution"] = @(FAinstitution); + tmp[@"fa-joomla"] = @(FAjoomla); + tmp[@"fa-jsfiddle"] = @(FAjsfiddle); + tmp[@"fa-language"] = @(FAlanguage); + tmp[@"fa-life-bouy"] = @(FAlifeBouy); + tmp[@"fa-life-ring"] = @(FAlifeRing); + tmp[@"fa-life-saver"] = @(FAlifeSaver); + tmp[@"fa-mortar-board"] = @(FAmortarBoard); + tmp[@"fa-openid"] = @(FAopenid); + tmp[@"fa-paper-plane"] = @(FApaperPlane); + tmp[@"fa-paper-plane-o"] = @(FApaperPlaneO); + tmp[@"fa-paragraph"] = @(FAparagraph); + tmp[@"fa-paw"] = @(FApaw); + tmp[@"fa-pied-piper"] = @(FApiedPiper); + tmp[@"fa-pied-piper-alt"] = @(FApiedPiperalt); + tmp[@"fa-pied-piper-square"] = @(FApiedPipersquare); + tmp[@"fa-qq"] = @(FAqq); + tmp[@"fa-ra"] = @(FAra); + tmp[@"fa-rebel"] = @(FArebel); + tmp[@"fa-recycle"] = @(FArecycle); + tmp[@"fa-reddit"] = @(FAreddit); + tmp[@"fa-reddit-square"] = @(FAredditSquare); + tmp[@"fa-send"] = @(FAsend); + tmp[@"fa-send-o"] = @(FAsendO); + tmp[@"fa-share-alt"] = @(FAshareAlt); + tmp[@"fa-share-alt-square"] = @(FAshareAltSquare); + tmp[@"fa-slack"] = @(FAslack); + tmp[@"fa-sliders"] = @(FAsliders); + tmp[@"fa-soundcloud"] = @(FAsoundcloud); + tmp[@"fa-space-shuttle"] = @(FAspaceShuttle); + tmp[@"fa-spoon"] = @(FAspoon); + tmp[@"fa-spotify"] = @(FAspotify); + tmp[@"fa-steam"] = @(FAsteam); + tmp[@"fa-steam-square"] = @(FAsteamSquare); + tmp[@"fa-stumbleupon"] = @(FAstumbleupon); + tmp[@"fa-stumbleupon-circle"] = @(FAstumbleuponCircle); + tmp[@"fa-support"] = @(FAsupport); + tmp[@"fa-taxi"] = @(FAtaxi); + tmp[@"fa-tencent-weibo"] = @(FAtencentWeibo); + tmp[@"fa-tree"] = @(FAtree); + tmp[@"fa-university"] = @(FAuniversity); + tmp[@"fa-vine"] = @(FAvine); + tmp[@"fa-wechat"] = @(FAwechat); + tmp[@"fa-weixin"] = @(FAweixin); + tmp[@"fa-wordpress"] = @(FAwordpress); + tmp[@"fa-yahoo"] = @(FAyahoo); + + /* FontAwesome ver 4.2.0 */ + tmp[@"fa-angellist"] = @(FAangellist); + tmp[@"fa-area-chart"] = @(FAareaChart); + tmp[@"fa-at"] = @(FAat); + tmp[@"fa-bell-slash"] = @(FAbellSlash); + tmp[@"fa-bell-slash-o"] = @(FAbellSlashO); + tmp[@"fa-bicycle"] = @(FAbicycle); + tmp[@"fa-binoculars"] = @(FAbinoculars); + tmp[@"fa-birthday-cake"] = @(FAbirthdayCake); + tmp[@"fa-bus"] = @(FAbus); + tmp[@"fa-calculator"] = @(FAcalculator); + tmp[@"fa-cc"] = @(FAcc); + tmp[@"fa-cc-amex"] = @(FAccAmex); + tmp[@"fa-cc-discover"] = @(FAccDiscover); + tmp[@"fa-cc-mastercard"] = @(FAccMastercard); + tmp[@"fa-cc-paypal"] = @(FAccPaypal); + tmp[@"fa-cc-stripe"] = @(FAccStripe); + tmp[@"fa-cc-visa"] = @(FAccVisa); + tmp[@"fa-copyright"] = @(FAcopyright); + tmp[@"fa-eyedropper"] = @(FAeyedropper); + tmp[@"fa-futbol-o"] = @(FAfutbolO); + tmp[@"fa-google-wallet"] = @(FAgoogleWallet); + tmp[@"fa-ils"] = @(FAils); + tmp[@"fa-ioxhost"] = @(FAioxhost); + tmp[@"fa-lastfm"] = @(FAlastfm); + tmp[@"fa-lastfm-square"] = @(FAlastfmSquare); + tmp[@"fa-line-chart"] = @(FAlineChart); + tmp[@"fa-meanpath"] = @(FAmeanpath); + tmp[@"fa-newspaper-o"] = @(FAnewspaperO); + tmp[@"fa-paint-brush"] = @(FApaintBrush); + tmp[@"fa-paypal"] = @(FApaypal); + tmp[@"fa-pie-chart"] = @(FApieChart); + tmp[@"fa-plug"] = @(FAplug); + tmp[@"fa-shekel"] = @(FAshekel); + tmp[@"fa-sheqel"] = @(FAsheqel); + tmp[@"fa-slideshare"] = @(FAslideshare); + tmp[@"fa-soccer-ball-o"] = @(FAsoccerBallO); + tmp[@"fa-toggle-off"] = @(FAtoggleOff); + tmp[@"fa-toggle-on"] = @(FAtoggleOn); + tmp[@"fa-trash"] = @(FAtrash); + tmp[@"fa-tty"] = @(FAtty); + tmp[@"fa-twitch"] = @(FAtwitch); + tmp[@"fa-wifi"] = @(FAwifi); + tmp[@"fa-yelp"] = @(FAyelp); + + /* FontAwesome ver 4.3.0 */ + tmp[@"fa-bed"] = @(FAbed); + tmp[@"fa-buysellads"] = @(FAbuysellads); + tmp[@"fa-cart-arrow-down"] = @(FAcartArrowDown); + tmp[@"fa-cart-plus"] = @(FAcartPlus); + tmp[@"fa-connectdevelop"] = @(FAconnectdevelop); + tmp[@"fa-dashcube"] = @(FAdashcube); + tmp[@"fa-diamond"] = @(FAdiamond); + tmp[@"fa-facebook-official"] = @(FAfacebookOfficial); + tmp[@"fa-forumbee"] = @(FAforumbee); + tmp[@"fa-heartbeat"] = @(FAheartbeat); + tmp[@"fa-hotel"] = @(FAhotel); + tmp[@"fa-leanpub"] = @(FAleanpub); + tmp[@"fa-mars"] = @(FAmars); + tmp[@"fa-mars-double"] = @(FAmarsDouble); + tmp[@"fa-mars-stroke"] = @(FAmarsStroke); + tmp[@"fa-mars-stroke-h"] = @(FAmarsStrokeH); + tmp[@"fa-mars-stroke-v"] = @(FAmarsStrokeV); + tmp[@"fa-medium"] = @(FAmedium); + tmp[@"fa-mercury"] = @(FAmercury); + tmp[@"fa-motorcycle"] = @(FAmotorcycle); + tmp[@"fa-neuter"] = @(FAneuter); + tmp[@"fa-pinterest-p"] = @(FApinterestP); + tmp[@"fa-sellsy"] = @(FAsellsy); + tmp[@"fa-server"] = @(FAserver); + tmp[@"fa-ship"] = @(FAship); + tmp[@"fa-shirtsinbulk"] = @(FAshirtsinbulk); + tmp[@"fa-simplybuilt"] = @(FAsimplybuilt); + tmp[@"fa-skyatlas"] = @(FAskyatlas); + tmp[@"fa-street-view"] = @(FAstreetView); + tmp[@"fa-subway"] = @(FAsubway); + tmp[@"fa-train"] = @(FAtrain); + tmp[@"fa-transgender"] = @(FAtransgender); + tmp[@"fa-transgender-alt"] = @(FAtransgenderAlt); + tmp[@"fa-user-plus"] = @(FAuserPlus); + tmp[@"fa-user-secret"] = @(FAuserSecret); + tmp[@"fa-user-times"] = @(FAuserTimes); + tmp[@"fa-venus"] = @(FAvenus); + tmp[@"fa-venus-double"] = @(FAvenusDouble); + tmp[@"fa-venus-mars"] = @(FAvenusMars); + tmp[@"fa-viacoin"] = @(FAviacoin); + + /* FontAwesome ver 4.4.0 */ + tmp[@"fa-500px"] = @(FA500px); + tmp[@"fa-amazon"] = @(FAamazon); + tmp[@"fa-balance-scale"] = @(FAbalanceScale); + tmp[@"fa-battery-empty"] = @(FAbatteryEmpty); + tmp[@"fa-battery-full"] = @(FAbatteryFull); + tmp[@"fa-battery-half"] = @(FAbatteryHalf); + tmp[@"fa-battery-quarter"] = @(FAbatteryQuarter); + tmp[@"fa-battery-three-quarters"] = @(FAbatteryThreeQuarters); + tmp[@"fa-black-tie"] = @(FAblackTie); + tmp[@"fa-calendar-check-o"] = @(FAcalendarCheckO); + tmp[@"fa-calendar-minus-o"] = @(FAcalendarMinusO); + tmp[@"fa-calendar-plus-o"] = @(FAcalendarPlusO); + tmp[@"fa-calendar-times-o"] = @(FAcalendarTimesO); + tmp[@"fa-cc-diners-club"] = @(FAccDinersClub); + tmp[@"fa-cc-jcb"] = @(FAccJcb); + tmp[@"fa-chrome"] = @(FAchrome); + tmp[@"fa-clone"] = @(FAclone); + tmp[@"fa-commenting"] = @(FAcommenting); + tmp[@"fa-commenting-o"] = @(FAcommentingO); + tmp[@"fa-contao"] = @(FAcontao); + tmp[@"fa-creative-commons"] = @(FAcreativeCommons); + tmp[@"fa-expeditedssl"] = @(FAexpeditedssl); + tmp[@"fa-firefox"] = @(FAfirefox); + tmp[@"fa-fonticons"] = @(FAfonticons); + tmp[@"fa-genderless"] = @(FAgenderless); + tmp[@"fa-get-pocket"] = @(FAgetPocket); + tmp[@"fa-gg"] = @(FAgg); + tmp[@"fa-gg-circle"] = @(FAggCircle); + tmp[@"fa-hand-lizard-o"] = @(FAhandLizardO); + tmp[@"fa-hand-paper-o"] = @(FAhandPaperO); + tmp[@"fa-hand-peace-o"] = @(FAhandPeaceO); + tmp[@"fa-hand-pointer-o"] = @(FAhandPointerO); + tmp[@"fa-hand-rock-o"] = @(FAhandRockO); + tmp[@"fa-hand-scissors-o"] = @(FAhandScissorsO); + tmp[@"fa-hand-spock-o"] = @(FAhandSpockO); + tmp[@"fa-hourglass"] = @(FAhourglass); + tmp[@"fa-hourglass-end"] = @(FAhourglassEnd); + tmp[@"fa-hourglass-half"] = @(FAhourglassHalf); + tmp[@"fa-hourglass-o"] = @(FAhourglassO); + tmp[@"fa-hourglass-start"] = @(FAhourglassStart); + tmp[@"fa-houzz"] = @(FAhouzz); + tmp[@"fa-i-cursor"] = @(FAiCursor); + tmp[@"fa-industry"] = @(FAindustry); + tmp[@"fa-internet-explorer"] = @(FAinternetExplorer); + tmp[@"fa-map"] = @(FAmap); + tmp[@"fa-map-o"] = @(FAmapO); + tmp[@"fa-map-pin"] = @(FAmapPin); + tmp[@"fa-map-signs"] = @(FAmapSigns); + tmp[@"fa-mouse-pointer"] = @(FAmousePointer); + tmp[@"fa-object-group"] = @(FAobjectGroup); + tmp[@"fa-object-ungroup"] = @(FAobjectUngroup); + tmp[@"fa-odnoklassniki"] = @(FAodnoklassniki); + tmp[@"fa-odnoklassniki-square"] = @(FAodnoklassnikiSquare); + tmp[@"fa-opencart"] = @(FAopencart); + tmp[@"fa-opera"] = @(FAopera); + tmp[@"fa-optin-monster"] = @(FAoptinMonster); + tmp[@"fa-registered"] = @(FAregistered); + tmp[@"fa-safari"] = @(FAsafari); + tmp[@"fa-sticky-note"] = @(FAstickyNote); + tmp[@"fa-sticky-note-o"] = @(FAstickyNoteO); + tmp[@"fa-television"] = @(FAtelevision); + tmp[@"fa-trademark"] = @(FAtrademark); + tmp[@"fa-tripadvisor"] = @(FAtripadvisor); + tmp[@"fa-vimeo"] = @(FAvimeo); + tmp[@"fa-wikipedia-w"] = @(FAwikipediaW); + tmp[@"fa-y-combinator"] = @(FAyCombinator); + enumDictionary = tmp; - } + }); return enumDictionary; } diff --git a/Demo/KoaPullToRefresh/Resources/UIFont+FontAwesome.h b/Demo/KoaPullToRefresh/Resources/UIFont+FontAwesome.h index cfa2b25..0668da4 100755 --- a/Demo/KoaPullToRefresh/Resources/UIFont+FontAwesome.h +++ b/Demo/KoaPullToRefresh/Resources/UIFont+FontAwesome.h @@ -26,7 +26,9 @@ @interface UIFont (FontAwesome) -/* Returns the FontAwesome iconic font */ -+ (UIFont*)iconicFontOfSize:(CGFloat)size; +/** + @abstract Returns the FontAwesome iconic font. + */ ++ (UIFont*)fontAwesomeFontOfSize:(CGFloat)size; @end diff --git a/Demo/KoaPullToRefresh/Resources/UIFont+FontAwesome.m b/Demo/KoaPullToRefresh/Resources/UIFont+FontAwesome.m index 0242d67..727e96e 100755 --- a/Demo/KoaPullToRefresh/Resources/UIFont+FontAwesome.m +++ b/Demo/KoaPullToRefresh/Resources/UIFont+FontAwesome.m @@ -11,10 +11,11 @@ @implementation UIFont (FontAwesome) -/* Returns the FontAwesome iconic font */ -+ (UIFont*)iconicFontOfSize:(CGFloat)size -{ - return [UIFont fontWithName:kFontAwesomeFamilyName size:size]; +#pragma mark - Public API ++ (UIFont*)fontAwesomeFontOfSize:(CGFloat)size { + UIFont *font = [UIFont fontWithName:kFontAwesomeFamilyName size:size]; + NSAssert(font!=nil, @"%@ couldn't be loaded",kFontAwesomeFamilyName); + return font; } @end diff --git a/Demo/KoaPullToRefresh/ViewController.m b/Demo/KoaPullToRefresh/ViewController.m index 3abc958..ef13a9b 100644 --- a/Demo/KoaPullToRefresh/ViewController.m +++ b/Demo/KoaPullToRefresh/ViewController.m @@ -50,7 +50,8 @@ - (void)viewDidLoad [self.tableView.pullToRefreshView setTextFont:[UIFont fontWithName:@"OpenSans-Semibold" size:16]]; //Set fontawesome icon - [self.tableView.pullToRefreshView setFontAwesomeIcon:@"icon-refresh"]; + + //[self.tableView.pullToRefreshView setFontAwesomeIcon:@"fa-refresh"]; //Set titles [self.tableView.pullToRefreshView setTitle:@"Pull" forState:KoaPullToRefreshStateStopped]; diff --git a/KoaPullToRefresh.podspec b/KoaPullToRefresh.podspec index e2819c3..4d36a1d 100644 --- a/KoaPullToRefresh.podspec +++ b/KoaPullToRefresh.podspec @@ -1,26 +1,21 @@ Pod::Spec.new do |s| s.name = 'KoaPullToRefresh' - s.version = '1.0.6' - s.platform = :ios, '5.0' + s.version = '1.1' + s.platform = :ios, '7.0' s.license = 'MIT' s.summary = 'Minimal & easily customizable pull-to-refresh control.' s.homepage = 'https://github.com/sergigracia/KoaPullToRefresh' - + s.author = { 'Sergi Gracia' => 'sergigram@gmail.com', 'Polina Flegontovna' => 'polina.flegontovna@gmail.com' } - s.source = { :git => 'https://github.com/sergigracia/KoaPullToRefresh.git', :tag => s.version.to_s } + s.source = { :git => 'https://github.com/tonimoeckel/KoaPullToRefresh.git', :tag => s.version.to_s } s.description = 'Add this custom, flat, minimal, modern pull-to-refresh ' \ 'control to your app. You can change the font, colors, size ' \ 'and even replace the spinning icon using FontAwesome. ' \ 'This library is very easy to add and customize. ' \ 'Enjoy.' - s.frameworks = 'QuartzCore' - - s.source_files = 'KoaPullToRefresh/*.{h,m}' - s.public_header_files = 'KoaPullToRefresh/*.h' + s.source_files = 'Classes', 'KoaPullToRefresh/*.{h,m}' s.dependency 'FontAwesome+iOS' - - s.preserve_paths = 'Demo' s.requires_arc = true -end \ No newline at end of file +end diff --git a/KoaPullToRefresh/KoaPullToRefresh.h b/KoaPullToRefresh/KoaPullToRefresh.h index 753b2bc..e17ed1b 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.h +++ b/KoaPullToRefresh/KoaPullToRefresh.h @@ -23,10 +23,6 @@ backgroundColor:(UIColor *)customBackgroundColor pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed; -- (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler - backgroundColor:(UIColor *)customBackgroundColor - pullToRefreshHeightShowed:(CGFloat)pullToRefreshHeightShowed; - - (void)addPullToRefreshWithActionHandler:(void (^)(void))actionHandler backgroundColor:(UIColor *)customBackgroundColor pullToRefreshHeight:(CGFloat)pullToRefreshHeight diff --git a/KoaPullToRefresh/KoaPullToRefresh.m b/KoaPullToRefresh/KoaPullToRefresh.m index e3afd66..818bac3 100644 --- a/KoaPullToRefresh/KoaPullToRefresh.m +++ b/KoaPullToRefresh/KoaPullToRefresh.m @@ -237,7 +237,11 @@ - (void)layoutSubviews self.titleLabel.text = [self.titles objectAtIndex:self.state]; //Set title frame - CGSize titleSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) lineBreakMode:self.titleLabel.lineBreakMode]; + NSStringDrawingOptions options = NSStringDrawingTruncatesLastVisibleLine | + NSStringDrawingUsesLineFragmentOrigin; + NSDictionary *attr = @{NSFontAttributeName: self.titleLabel.font}; + + CGSize titleSize = [self.titleLabel.text boundingRectWithSize:CGSizeMake(labelMaxWidth,self.titleLabel.font.lineHeight) options:options attributes:attr context:nil].size; CGFloat titleY = KoaPullToRefreshViewHeight - KoaPullToRefreshViewHeightShowed - titleSize.height - KoaPullToRefreshViewTitleBottomMargin; [self.titleLabel setFrame:CGRectIntegral(CGRectMake(0, titleY, self.frame.size.width, titleSize.height))]; @@ -339,7 +343,7 @@ - (void)scrollViewDidScroll:(CGPoint)contentOffset } //Change title label alpha - CGFloat absOffset = fabsf(self.originalTopInset); + CGFloat absOffset = fabs(self.originalTopInset); absOffset /= contentOffset.y; absOffset = 1.4 + absOffset; [self.titleLabel setAlpha:absOffset]; @@ -367,7 +371,7 @@ - (void)scrollViewDidScroll:(CGPoint)contentOffset //Set content offset for special cases if(self.state != KoaPullToRefreshStateLoading) { if (self.scrollView.contentOffset.y > -KoaPullToRefreshViewHeightShowed && self.scrollView.contentOffset.y < 0) { - [self.scrollView setContentInset:UIEdgeInsetsMake(self.originalTopInset + abs(self.scrollView.contentOffset.y), + [self.scrollView setContentInset:UIEdgeInsetsMake(self.originalTopInset + fabs(self.scrollView.contentOffset.y), self.scrollView.contentInset.left, self.scrollView.contentInset.bottom, self.scrollView.contentInset.right)]; @@ -393,9 +397,10 @@ - (UILabel *)titleLabel { - (UILabel *)loaderLabel { if(!_loaderLabel) { - _loaderLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.frame.size.width/2 - 17/2, 0, 17, 17)]; + float size = 20; + _loaderLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.frame.size.width/2 - size/2, 0, size, size)]; _loaderLabel.text = [NSString fontAwesomeIconStringForIconIdentifier:self.fontAwesomeIcon]; - _loaderLabel.font = [UIFont fontWithName:kFontAwesomeFamilyName size:20]; + _loaderLabel.font = [UIFont fontWithName:kFontAwesomeFamilyName size:size]; _loaderLabel.backgroundColor = [UIColor clearColor]; _loaderLabel.textColor = textColor; [_loaderLabel sizeToFit]; @@ -406,7 +411,7 @@ - (UILabel *)loaderLabel { - (NSString *)fontAwesomeIcon { if (!_fontAwesomeIcon) { - _fontAwesomeIcon = @"fa-refresh"; + _fontAwesomeIcon = @"fa-circle-o-notch"; } return _fontAwesomeIcon; }