小说绘上架版本
This commit is contained in:
+15
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// YJAbstractDotView.h
|
||||
// YJBannerViewDemo
|
||||
//
|
||||
// Created by YJHou on 2015/5/24.
|
||||
// Copyright © Address:https://github.com/stackhou . All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface YJAbstractDotView : UIView
|
||||
|
||||
- (void)changeActivityState:(BOOL)active;
|
||||
|
||||
@end
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// YJAbstractDotView.m
|
||||
// YJBannerViewDemo
|
||||
//
|
||||
// Created by YJHou on 2015/5/24.
|
||||
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
|
||||
//
|
||||
|
||||
#import "YJAbstractDotView.h"
|
||||
|
||||
@implementation YJAbstractDotView
|
||||
|
||||
- (id)init{
|
||||
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
||||
reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class]
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void)changeActivityState:(BOOL)active{
|
||||
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
||||
reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class]
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// YJAnimatedDotView.h
|
||||
// YJBannerViewDemo
|
||||
//
|
||||
// Created by YJHou on 2015/5/24.
|
||||
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
|
||||
//
|
||||
|
||||
#import "YJAbstractDotView.h"
|
||||
|
||||
@interface YJAnimatedDotView : YJAbstractDotView
|
||||
|
||||
@property (nonatomic, strong) UIColor *dotColor;
|
||||
@property (nonatomic, strong) UIColor *currentDotColor;
|
||||
@property (nonatomic, assign) CGFloat resizeScale; /**< 调整比例 */
|
||||
|
||||
@end
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// YJAnimatedDotView.m
|
||||
// YJBannerViewDemo
|
||||
//
|
||||
// Created by YJHou on 2015/5/24.
|
||||
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
|
||||
//
|
||||
|
||||
#import "YJAnimatedDotView.h"
|
||||
|
||||
static CGFloat const kAnimateDuration = 0;
|
||||
|
||||
@implementation YJAnimatedDotView
|
||||
|
||||
- (instancetype)init{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self initialization];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self initialization];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)aDecoder{
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if (self) {
|
||||
[self initialization];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setDotColor:(UIColor *)dotColor{
|
||||
_dotColor = dotColor;
|
||||
self.layer.borderColor = dotColor.CGColor;
|
||||
}
|
||||
|
||||
- (void)setCurrentDotColor:(UIColor *)currentDotColor{
|
||||
_currentDotColor = currentDotColor;
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
}
|
||||
|
||||
- (void)initialization{
|
||||
_dotColor = [UIColor whiteColor];
|
||||
_currentDotColor = [UIColor whiteColor];
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
self.layer.cornerRadius = CGRectGetWidth(self.frame) * 0.5;
|
||||
self.layer.borderColor = [UIColor whiteColor].CGColor;
|
||||
self.layer.borderWidth = 1.5;
|
||||
self.resizeScale = 1.4f;
|
||||
}
|
||||
|
||||
- (void)changeActivityState:(BOOL)active{
|
||||
if (active) {
|
||||
[self animateToActiveState];
|
||||
} else {
|
||||
[self animateToDeactiveState];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)animateToActiveState{
|
||||
[UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:-20 options:UIViewAnimationOptionCurveLinear animations:^{
|
||||
self.backgroundColor = self.currentDotColor;
|
||||
self.layer.borderColor = [UIColor clearColor].CGColor;
|
||||
self.transform = CGAffineTransformMakeScale(self.resizeScale, self.resizeScale);
|
||||
} completion:nil];
|
||||
}
|
||||
|
||||
- (void)animateToDeactiveState{
|
||||
[UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
self.layer.borderColor = self.dotColor.CGColor;
|
||||
self.transform = CGAffineTransformIdentity;
|
||||
} completion:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// YJHollowPageControl.h
|
||||
// YJBannerViewDemo
|
||||
//
|
||||
// Created by YJHou on 2015/5/24.
|
||||
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "YJAbstractDotView.h"
|
||||
|
||||
@class YJHollowPageControl;
|
||||
@protocol YJHollowPageControlDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
- (void)yjHollowPageControl:(YJHollowPageControl *)pageControl didSelectPageAtIndex:(NSInteger)index;
|
||||
|
||||
@end
|
||||
|
||||
@interface YJHollowPageControl : UIControl
|
||||
|
||||
@property (nonatomic, assign) CGSize dotSize; /**< 圆点大小 默认8*8 */
|
||||
@property (nonatomic, strong) UIImage *dotNormalImage; /**< 普通样式 */
|
||||
@property (nonatomic, strong) UIImage *dotCurrentImage; /**< 选中样式 */
|
||||
|
||||
@property (nonatomic, strong) UIColor *dotNormalColor; /**< 点色 */
|
||||
@property (nonatomic, strong) UIColor *dotCurrentColor; /**< 当前圆点的颜色 */
|
||||
|
||||
@property (nonatomic, strong) Class dotViewClass; /**< 圆点类 */
|
||||
@property (nonatomic, weak) id<YJHollowPageControlDelegate> delegate; /**< 代理 */
|
||||
@property (nonatomic, assign) CGFloat spacing; /**< 间距 默认 8 */
|
||||
@property (nonatomic, assign) NSInteger numberOfPages; /**< 数量 */
|
||||
@property (nonatomic, assign) NSInteger currentPage; /**< 当前位置 */
|
||||
@property (nonatomic, assign) BOOL hidesForSinglePage; /**< 单个不显示 默认NO*/
|
||||
@property (nonatomic, assign) BOOL shouldResizeFromCenter; /**< 是否调整大小 */
|
||||
@property (nonatomic, assign) CGFloat resizeScale; /**< 调整比例 */
|
||||
|
||||
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface YJDotView : YJAbstractDotView
|
||||
|
||||
@end
|
||||
+322
@@ -0,0 +1,322 @@
|
||||
//
|
||||
// YJHollowPageControl.m
|
||||
// YJBannerViewDemo
|
||||
//
|
||||
// Created by YJHou on 2015/5/24.
|
||||
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
|
||||
//
|
||||
|
||||
#import "YJHollowPageControl.h"
|
||||
#import "YJAnimatedDotView.h"
|
||||
|
||||
static CGSize const kDefaultDotSize = {8, 8};
|
||||
static NSInteger const kDefaultNumberOfPages = 0;
|
||||
static NSInteger const kDefaultCurrentPage = 0;
|
||||
static BOOL const kDefaultHideForSinglePage = NO;
|
||||
static BOOL const kDefaultShouldResizeFromCenter = YES;
|
||||
static NSInteger const kDefaultSpacingBetweenDots = 8;
|
||||
|
||||
@interface YJHollowPageControl ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray *dots; /**< 保存所有的点 */
|
||||
|
||||
@end
|
||||
|
||||
@implementation YJHollowPageControl
|
||||
|
||||
- (id)init{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _initializationSetting];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self _initializationSetting];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)aDecoder{
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if (self) {
|
||||
[self _initializationSetting];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_initializationSetting{
|
||||
self.dotViewClass = [YJAnimatedDotView class];
|
||||
self.spacing = kDefaultSpacingBetweenDots;
|
||||
self.numberOfPages = kDefaultNumberOfPages;
|
||||
self.currentPage = kDefaultCurrentPage;
|
||||
self.hidesForSinglePage = kDefaultHideForSinglePage;
|
||||
self.shouldResizeFromCenter = kDefaultShouldResizeFromCenter;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Touch event
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
|
||||
UITouch *touch = [touches anyObject];
|
||||
if (touch.view != self) {
|
||||
NSInteger index = [self.dots indexOfObject:touch.view];
|
||||
if ([self.delegate respondsToSelector:@selector(yjHollowPageControl:didSelectPageAtIndex:)]) {
|
||||
[self.delegate yjHollowPageControl:self didSelectPageAtIndex:index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sizeToFit{
|
||||
[self updateFrame:YES];
|
||||
}
|
||||
|
||||
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount{
|
||||
return CGSizeMake((self.dotSize.width + self.spacing) * pageCount - self.spacing , self.dotSize.height);
|
||||
}
|
||||
|
||||
|
||||
- (void)updateDots{
|
||||
if (self.numberOfPages == 0) {return;}
|
||||
|
||||
for (NSInteger i = 0; i < self.numberOfPages; i++) {
|
||||
|
||||
UIView *dot;
|
||||
if (i < self.dots.count) {
|
||||
dot = [self.dots objectOrNilAtIndex:i];
|
||||
} else {
|
||||
dot = [self generateDotView];
|
||||
}
|
||||
[self updateDotFrame:dot atIndex:i];
|
||||
}
|
||||
[self changeActivity:YES atIndex:self.currentPage];
|
||||
|
||||
[self hideForSinglePage];
|
||||
}
|
||||
|
||||
/**
|
||||
Update frame to fit current number of pages.
|
||||
|
||||
@param newFrame override Existing Frame
|
||||
*/
|
||||
- (void)updateFrame:(BOOL)newFrame{
|
||||
CGPoint center = self.center;
|
||||
CGSize requiredSize = [self sizeForNumberOfPages:self.numberOfPages];
|
||||
|
||||
// We apply requiredSize only if authorize to and necessary
|
||||
if (newFrame || ((CGRectGetWidth(self.frame) < requiredSize.width || CGRectGetHeight(self.frame) < requiredSize.height) && !newFrame)) {
|
||||
self.frame = CGRectMake(CGRectGetMinX(self.frame), CGRectGetMinY(self.frame), requiredSize.width, requiredSize.height);
|
||||
if (self.shouldResizeFromCenter) {
|
||||
self.center = center;
|
||||
}
|
||||
}
|
||||
[self resetDotViews];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the frame of a specific dot at a specific index
|
||||
*
|
||||
* @param dot Dot view
|
||||
* @param index Page index of dot
|
||||
*/
|
||||
- (void)updateDotFrame:(UIView *)dot atIndex:(NSInteger)index{
|
||||
// Dots are always centered within view
|
||||
CGFloat x = (self.dotSize.width + self.spacing) * index + ( (CGRectGetWidth(self.frame) - [self sizeForNumberOfPages:self.numberOfPages].width) / 2);
|
||||
CGFloat y = (CGRectGetHeight(self.frame) - self.dotSize.height) / 2;
|
||||
|
||||
dot.frame = CGRectMake(x, y, self.dotSize.width, self.dotSize.height);
|
||||
}
|
||||
|
||||
- (void)setDotCurrentColor:(UIColor *)currentDotColor{
|
||||
_dotCurrentColor = currentDotColor;
|
||||
}
|
||||
|
||||
- (void)setDotNormalColor:(UIColor *)dotColor{
|
||||
_dotNormalColor = dotColor;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Utils
|
||||
/**
|
||||
* Generate a dot view and add it to the collection
|
||||
*
|
||||
* @return The UIView object representing a dot
|
||||
*/
|
||||
- (UIView *)generateDotView{
|
||||
UIView *dotView;
|
||||
|
||||
if (self.dotViewClass) {
|
||||
dotView = [[self.dotViewClass alloc] initWithFrame:CGRectMake(0, 0, self.dotSize.width, self.dotSize.height)];
|
||||
if ([dotView isKindOfClass:[YJAnimatedDotView class]]) {
|
||||
if (self.resizeScale > 0) {
|
||||
((YJAnimatedDotView *)dotView).resizeScale = self.resizeScale;
|
||||
}
|
||||
if (self.dotNormalColor) {
|
||||
((YJAnimatedDotView *)dotView).dotColor = self.dotNormalColor;
|
||||
}
|
||||
if (self.dotCurrentColor){
|
||||
((YJAnimatedDotView *)dotView).currentDotColor = self.dotCurrentColor;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dotView = [[UIImageView alloc] initWithImage:self.dotNormalImage];
|
||||
dotView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
dotView.frame = CGRectMake(0, 0, self.dotSize.width, self.dotSize.height);
|
||||
}
|
||||
|
||||
if (dotView) {
|
||||
[self addSubview:dotView];
|
||||
[self.dots addObject:dotView];
|
||||
}
|
||||
|
||||
dotView.userInteractionEnabled = YES;
|
||||
return dotView;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change activity state of a dot view. Current/not currrent.
|
||||
*
|
||||
* @param active Active state to apply
|
||||
* @param index Index of dot for state update
|
||||
*/
|
||||
- (void)changeActivity:(BOOL)active atIndex:(NSInteger)index{
|
||||
if (self.dotViewClass) {
|
||||
YJAbstractDotView *abstractDotView = (YJAbstractDotView *)[self.dots objectOrNilAtIndex:index];
|
||||
if ([abstractDotView respondsToSelector:@selector(changeActivityState:)]) {
|
||||
[abstractDotView changeActivityState:active];
|
||||
} else {
|
||||
|
||||
}
|
||||
} else if (self.dotNormalImage && self.dotCurrentImage) {
|
||||
UIImageView *dotView = (UIImageView *)[self.dots objectOrNilAtIndex:index];
|
||||
dotView.image = (active) ? self.dotCurrentImage : self.dotNormalImage;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)resetDotViews{
|
||||
for (UIView *dotView in self.dots) {
|
||||
[dotView removeFromSuperview];
|
||||
}
|
||||
[self.dots removeAllObjects];
|
||||
[self updateDots];
|
||||
}
|
||||
|
||||
- (void)hideForSinglePage{
|
||||
if (self.dots.count == 1 && self.hidesForSinglePage) {
|
||||
self.hidden = YES;
|
||||
} else {
|
||||
self.hidden = NO;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Setters
|
||||
- (void)setNumberOfPages:(NSInteger)numberOfPages{
|
||||
_numberOfPages = numberOfPages;
|
||||
// Update dot position to fit new number of pages
|
||||
[self resetDotViews];
|
||||
}
|
||||
|
||||
- (void)setSpacing:(CGFloat)spacing{
|
||||
_spacing = spacing;
|
||||
[self resetDotViews];
|
||||
}
|
||||
|
||||
- (void)setCurrentPage:(NSInteger)currentPage{
|
||||
// If no pages, no current page to treat.
|
||||
if (self.numberOfPages == 0 || currentPage == _currentPage) {
|
||||
_currentPage = currentPage;
|
||||
return;
|
||||
}
|
||||
|
||||
// Pre set
|
||||
[self changeActivity:NO atIndex:_currentPage];
|
||||
_currentPage = currentPage;
|
||||
// Post set
|
||||
[self changeActivity:YES atIndex:_currentPage];
|
||||
}
|
||||
|
||||
- (void)setDotNormalImage:(UIImage *)dotImage{
|
||||
_dotNormalImage = dotImage;
|
||||
[self resetDotViews];
|
||||
self.dotViewClass = nil;
|
||||
}
|
||||
|
||||
- (void)setDotCurrentImage:(UIImage *)currentDotimage{
|
||||
_dotCurrentImage = currentDotimage;
|
||||
[self resetDotViews];
|
||||
self.dotViewClass = nil;
|
||||
}
|
||||
|
||||
- (void)setDotViewClass:(Class)dotViewClass{
|
||||
_dotViewClass = dotViewClass;
|
||||
self.dotSize = CGSizeZero;
|
||||
[self resetDotViews];
|
||||
}
|
||||
|
||||
#pragma mark - Getter
|
||||
- (CGSize)dotSize{
|
||||
if (self.dotNormalImage && CGSizeEqualToSize(_dotSize, CGSizeZero)) {
|
||||
_dotSize = self.dotNormalImage.size;
|
||||
} else if (self.dotViewClass && CGSizeEqualToSize(_dotSize, CGSizeZero)) {
|
||||
_dotSize = kDefaultDotSize;
|
||||
return _dotSize;
|
||||
}
|
||||
return _dotSize;
|
||||
}
|
||||
|
||||
#pragma mark - Lazy
|
||||
- (NSMutableArray *)dots{
|
||||
if (!_dots) {
|
||||
_dots = [NSMutableArray array];
|
||||
}
|
||||
return _dots;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation YJDotView
|
||||
|
||||
- (instancetype)init{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _initializationSetting];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self _initializationSetting];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)aDecoder{
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if (self) {
|
||||
[self _initializationSetting];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_initializationSetting{
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
self.layer.cornerRadius = CGRectGetWidth(self.frame) * 0.5;
|
||||
self.layer.borderColor = [UIColor whiteColor].CGColor;
|
||||
self.layer.borderWidth = 2;
|
||||
}
|
||||
|
||||
- (void)changeActivityState:(BOOL)active{
|
||||
if (active) {
|
||||
self.backgroundColor = [UIColor whiteColor];
|
||||
} else {
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user