Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions RCPageControl/RCAbstractIndicatorView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// RCAbstractIndicatorView.h
// Pods
//
// Created by Simo ++ on 18/10/2015.
//
//

#import <UIKit/UIKit.h>

@interface RCAbstractIndicatorView : UIView

- (void)updateState:(BOOL)isCurrent;

@end
27 changes: 27 additions & 0 deletions RCPageControl/RCAbstractIndicatorView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// RCAbstractIndicatorView.m
// Pods
//
// Created by Simo ++ on 18/10/2015.
//
//

#import "RCAbstractIndicatorView.h"

@implementation RCAbstractIndicatorView

- (instancetype)init {

@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class]
userInfo:nil];
}

- (void)updateState:(BOOL)isCurrent {

@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class]
userInfo:nil];
}

@end
4 changes: 4 additions & 0 deletions RCPageControl/RCPageControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
*/

#import <UIKit/UIKit.h>
#import "RCAbstractIndicatorView.h"

@class RCPageControl;

Expand Down Expand Up @@ -60,9 +61,12 @@ typedef void (^RCCurrentPageChangedBlock)(RCPageControl *pageControl);

@property(nonatomic) UIFont *currentPageIndexTextFont; // default is [UIFont systemFontOfSize:0], the font size is automatically adjusts by the value of indicatorDotWidth and animationScaleFactor

@property (nonatomic, readonly) Class pageIndicatorViewClass; //to use custom indicator view class, must use 'initWithPageControlClass'.

@property (nonatomic, copy) RCCurrentPageChangedBlock currentPageChangedBlock; // if set, -sendActionsForControlEvents will never be called, only available for 'Touch Event' in page control, it also means you need to set non-zero frame for page control to activate 'Touch Event'

- (instancetype)initWithNumberOfPages:(NSInteger)pages; // if you want 'currentPageChanged' block available, call -setFrame: after initialization
- (instancetype)initWithPageControlClass:(Class)class;

- (void)updateCurrentPageDisplay; // update page display to match the currentPage, ignored if defersCurrentPageDisplay is NO, setting the page value directly will update immediately

Expand Down
51 changes: 47 additions & 4 deletions RCPageControl/RCPageControl.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ of this software and associated documentation files (the "Software"), to deal
#define RCDefaultIndicatorColorAnimationKey @"RCPageControlIndicatorColorAnimation"
#define RCDefaultIndicatorIndexLabelAlphaAnimationKey @"RCDefaultIndicatorIndexLabelAlphaAnimationKey"

#define IsFloatZero(A) fabsf(A) < FLT_EPSILON
#define IsFloatZero(A) fabs(A) < FLT_EPSILON
#define IsFloatEqualToFloat(A, B) IsFloatZero((A) - (B))

@interface RCPageControl ()
Expand Down Expand Up @@ -87,6 +87,16 @@ - (instancetype)initWithNumberOfPages:(NSInteger)pages {
return pageControl;
}

- (instancetype)initWithPageControlClass:(Class)class {
RCPageControl *pageControl = [self init];

if (class) {
[pageControl setPageIndicatorViewClass:class];
}

return pageControl;
}

- (void)awakeFromNib {
[self commConfig];
}
Expand Down Expand Up @@ -253,6 +263,13 @@ - (void)setCurrentPageIndexTextFont:(UIFont *)currentPageIndexTextFont {
}
}

- (void)setPageIndicatorViewClass:(Class)pageIndicatorViewClass {
if ( ![_pageIndicatorViewClass isEqual:pageIndicatorViewClass]) {
_pageIndicatorViewClass = pageIndicatorViewClass;
[self _refreshIndicator:YES];
}
}

#pragma mark - Touch Event

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
Expand Down Expand Up @@ -357,6 +374,16 @@ - (void)_dotScaleAnimationAtIndex:(NSInteger)index withProgress:(CGFloat)progres
}

- (void)_dotColorAnimationAtIndex:(NSInteger)index withProgress:(CGFloat)progress {

if (self.pageIndicatorViewClass) {

RCAbstractIndicatorView *view = (RCAbstractIndicatorView *)[self _dotAtIndex:index];

if ([view respondsToSelector:@selector(updateState:)]) {
[view updateState:(index == _currentDisplayedPage) ? YES : NO];
}
}

[self _dotColorAnimationAtIndex:index toValue:(index == _currentDisplayedPage) ? _currentPageIndicatorTintColor : _pageIndicatorTintColor];
}

Expand Down Expand Up @@ -406,7 +433,25 @@ - (void)_refreshIndicator:(BOOL)forceRefresh {

for (; index < _numberOfPages; index ++) {
CGRect frame = CGRectMake(position.x + index * (_indicatorDotGap + _indicatorDotWidth), position.y, _indicatorDotWidth, _indicatorDotWidth);
UIView *dot = [self _dotAtIndex:index] ?: [[UIView alloc] initWithFrame:frame];

UIView *dot;

if ([self _dotAtIndex:index]) {
dot = [self _dotAtIndex:index];
} else {
if (_pageIndicatorViewClass) {

dot = (RCAbstractIndicatorView *)[[_pageIndicatorViewClass alloc] initWithFrame:frame];

if ([dot respondsToSelector:@selector(updateState:)]) {
[(RCAbstractIndicatorView *)dot updateState:(index == _currentDisplayedPage) ? YES : NO];
}

} else {
dot = [[UIView alloc] initWithFrame:frame];
[dot.layer setCornerRadius:(frame.size.width/2)];
}
}

if ([UIView respondsToSelector:@selector(performWithoutAnimation:)]) {
[UIView performWithoutAnimation:^{
Expand All @@ -421,9 +466,7 @@ - (void)_refreshIndicator:(BOOL)forceRefresh {

[dot setTag:[self _dotTagAtIndex:index]];
[dot setBackgroundColor:_pageIndicatorTintColor];

[dot.layer setMasksToBounds:YES];
[dot.layer setCornerRadius:dot.frame.size.height / 2];

if ( !dot.superview) {
[self addSubview:dot];
Expand Down
14 changes: 7 additions & 7 deletions RCPageControlExample/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PODS:
- iCarousel (1.8.1)
- pop (1.0.7)
- RCPageControl (0.1):
- iCarousel (1.8.2)
- pop (1.0.8)
- RCPageControl (0.1.1):
- pop

DEPENDENCIES:
Expand All @@ -14,8 +14,8 @@ EXTERNAL SOURCES:
:path: ../

SPEC CHECKSUMS:
iCarousel: 5acab560f10dc13da2440c89f35a0ad278b5147d
pop: 2f14a1ea61339767af9e66741b418c831b3844df
RCPageControl: bdfb2c9322b41bc4e4a166e585f4a6564e14643b
iCarousel: 67c8a43da5a46795b56aadfc96cd36a16f6149b2
pop: bb773ae2c791ca2629de13b347e7a8b450fa6a57
RCPageControl: d7f6a8f5e1f9ca9a8ed7dbe32b5c266cf2844070

COCOAPODS: 0.36.0.rc.1
COCOAPODS: 0.39.0
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
6E2F734619C72601008985F7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6E2F734519C72601008985F7 /* Images.xcassets */; };
6E2F734919C72601008985F7 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6E2F734719C72601008985F7 /* LaunchScreen.xib */; };
6E2F735519C72601008985F7 /* RCPageControlExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E2F735419C72601008985F7 /* RCPageControlExampleTests.m */; };
B266C4C91BD3DD6500604FD1 /* CustomIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = B266C4C81BD3DD6500604FD1 /* CustomIndicatorView.m */; settings = {ASSET_TAGS = (); }; };
D49C37915C534FBF81B1C62C /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E1326DC0F37B4CD9B3DC981C /* libPods.a */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -45,6 +46,8 @@
6E2F735319C72601008985F7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6E2F735419C72601008985F7 /* RCPageControlExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCPageControlExampleTests.m; sourceTree = "<group>"; };
6E55D24919C97C01008E8B03 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
B266C4C71BD3DD6500604FD1 /* CustomIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomIndicatorView.h; sourceTree = "<group>"; };
B266C4C81BD3DD6500604FD1 /* CustomIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomIndicatorView.m; sourceTree = "<group>"; };
DAF73DA31F7F816C3C0D9AD6 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
E1326DC0F37B4CD9B3DC981C /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -95,6 +98,8 @@
6E2F733D19C72600008985F7 /* AppDelegate.m */,
6E2F733F19C72600008985F7 /* ViewController.h */,
6E2F734019C72600008985F7 /* ViewController.m */,
B266C4C71BD3DD6500604FD1 /* CustomIndicatorView.h */,
B266C4C81BD3DD6500604FD1 /* CustomIndicatorView.m */,
6E2F734219C72600008985F7 /* Main.storyboard */,
6E2F734519C72601008985F7 /* Images.xcassets */,
6E2F734719C72601008985F7 /* LaunchScreen.xib */,
Expand Down Expand Up @@ -160,6 +165,7 @@
6E2F733219C72600008985F7 /* Frameworks */,
6E2F733319C72600008985F7 /* Resources */,
4205A7A3089C4258B519BEEC /* Copy Pods Resources */,
C44C854C1AC0DA35B6023388 /* Embed Pods Frameworks */,
);
buildRules = (
);
Expand Down Expand Up @@ -277,6 +283,21 @@
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
C44C854C1AC0DA35B6023388 /* Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
Expand All @@ -287,6 +308,7 @@
6E2F734119C72600008985F7 /* ViewController.m in Sources */,
6E2F733E19C72600008985F7 /* AppDelegate.m in Sources */,
6E2F733B19C72600008985F7 /* main.m in Sources */,
B266C4C91BD3DD6500604FD1 /* CustomIndicatorView.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
14 changes: 14 additions & 0 deletions RCPageControlExample/RCPageControlExample/CustomIndicatorView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// CustomIndicatorView.h
// RCPageControlExample
//
// Created by Simo ++ on 18/10/2015.
// Copyright © 2015 RidgeCorn. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "RCAbstractIndicatorView.h"

@interface CustomIndicatorView : RCAbstractIndicatorView

@end
56 changes: 56 additions & 0 deletions RCPageControlExample/RCPageControlExample/CustomIndicatorView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// CustomIndicatorView.m
// RCPageControlExample
//
// Created by Simo ++ on 18/10/2015.
// Copyright © 2015 RidgeCorn. All rights reserved.
//

#import "CustomIndicatorView.h"

@interface CustomIndicatorView()

@property (nonatomic) UIImageView *imageView;

@end

@implementation CustomIndicatorView

#pragma mark - Properties

- (UIImageView *)imageView {
if (!_imageView) {
_imageView = [UIImageView new];
_imageView.backgroundColor = [UIColor clearColor];
}
return _imageView;
}

#pragma mark - Lifecycle

- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {

[self addSubview:self.imageView];
}
return self;
}

- (void)layoutSubviews {
[super layoutSubviews];

self.layer.cornerRadius = (self.frame.size.width/2);
self.imageView.frame = self.bounds;
}

- (void)updateState:(BOOL)isCurrent {

//customize your indicator view here.

UIImage *image = isCurrent ? [UIImage imageNamed:@"Happy"] : [UIImage imageNamed:@"Sad"];
[self.imageView setImage:image];
}

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Emoticons Happy.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Emoticons Sad.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading