#import <UIKit/UIKit.h>
typedef void(^SelectedBlock)(id viewPager, NSInteger index);
@interface YFViewPager : UIView<UIScrollViewDelegate>
{
NSArray *_titleArray; /**< 菜单标题 */
NSArray *_views; /**< 视图 */
NSArray *_titleIconsArray; /**< 菜单标题左侧的小图标 */
NSArray *_selectedIconsArray; /**< 菜单被选中时左侧的小图标 */
NSArray *_tipsCountArray; /**< 菜单右上角的小红点显示的数量 */
}
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIView *pageControl;
/**
* 设置viewPager是否允许滚动 默认支持
*/
@property (nonatomic, assign) BOOL enabledScroll;
/**
* 当前选择的菜单索引
*/
@property (nonatomic, assign) NSInteger selectIndex;
/**
* 菜单按钮背景属性
*/
@property (nonatomic, strong) UIColor *tabBgColor;
@property (nonatomic, strong) UIColor *tabSelectedBgColor;
/**
* 菜单按钮下方横线背景属性
*/
@property (nonatomic, strong) UIColor *tabArrowBgColor;
@property (nonatomic, strong) UIColor *tabSelectedArrowBgColor;
/**
* 菜单按钮的标题颜色属性
*/
@property (nonatomic, strong) UIColor *tabTitleColor;
@property (nonatomic, strong) UIColor *tabSelectedTitleColor;
/**
* 是否显示垂直分割线 默认显示
*/
@property (nonatomic, assign) BOOL showVLine;
/**
* 是否显示底部横线 默认显示
*/
@property (nonatomic, assign) BOOL showBottomLine;
/**
* 选中状态是否显示底部横线 默认显示
*/
@property (nonatomic, assign) BOOL showSelectedBottomLine;
/**
* 是否显示垂直分割线 默认显示
*/
@property (nonatomic, assign) BOOL showAnimation;
/**
* 初始化 YFViewPager的方法
*
* @param frame frame
* @param titles 标题数组
* @param views 视图数组 和标题数组一一对应
*
* @return YFViewPager
*/
- (id)initWithFrame:(CGRect)frame
titles:(NSArray<NSString *> *)titles
views:(NSArray<__kindof UIView *> *)views;
/**
* 设置选择的菜单按钮
*
* @param index 按钮的索引值 从左到右一次是0,1,2,3...
*/
- (void)setSelectIndex:(NSInteger)index;
/**
* 点击菜单按钮时 调用的block方法
*
* @param block 返回YFViewPager本身和点击的按钮的索引值,从左到右一次是0,1,2,3...
*/
- (void)didSelectedBlock:(SelectedBlock)block;
#pragma mark - version 2.0
/**
* 初始化 YFViewPager的方法
*
* @param frame frame
* @param titles 标题数组
* @param icons 标题右侧图标数组
* @param selectedIcons 标题右侧选中时的图标数组
* @param views 视图数组 和标题数组一一对应
*
* @return YFViewPager
*/
- (id)initWithFrame:(CGRect)frame
titles:(NSArray<NSString *> *)titles
icons:(NSArray<UIImage *> *)icons
selectedIcons:(NSArray<UIImage *> *)selectedIcons
views:(NSArray<__kindof UIView *> *)views;
/**
* 设置菜单标题左边的icon 图标
*
* @param icons 图标image
* @param selectedIcons 菜单被选中时显示的图标image
*/
- (void)setTitleIconsArray:(NSArray<UIImage *> *)icons selectedIconsArray:(NSArray<UIImage *> *)selectedIcons;
/**
* 设置菜单右上角小红点显示的文字,数组需与菜单一一对应,数字为0时 赋值 @0或@""
*
* @param tips 小红点上的文字
*/
- (void)setTipsCountArray:(NSArray *)tips;
@end
#import "YFViewPager.h"
#import "Public.h"
#ifdef DEBUG
#define DLog(s, ...) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DLog(s, ...)
#endif
@implementation YFViewPager
{
SelectedBlock _block;
NSInteger _pageNum;
}
//初始化
- (id)initWithFrame:(CGRect)frame
titles:(NSArray<NSString *> *)titles
views:(NSArray<__kindof UIView *> *)views
{
self = [super initWithFrame:frame];
if (self) {
_views = views;
_titleArray = titles;
self.backgroundColor = [UIColor grayColor];
[self configSelf];
}
return self;
}
//设置默认属性
- (void)configSelf
{
self.userInteractionEnabled = YES;
_tabBgColor = RGB(235, 235, 235);
_tabArrowBgColor = [UIColor orangeColor];
_tabTitleColor = [UIColor grayColor];
_tabSelectedBgColor =RGB(235, 235, 235);
_tabSelectedTitleColor = [UIColor orangeColor];
_tabSelectedArrowBgColor =[UIColor orangeColor];
_showVLine = NO;
_showAnimation = YES;
_showBottomLine = NO;
_showSelectedBottomLine = YES;
_enabledScroll = YES;
}
//视图重绘
- (void)drawRect:(CGRect)rect
{
// Drawing code
_scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 2, rect.size.width, rect.size.height - 2)];
_scrollView.userInteractionEnabled = YES;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.pagingEnabled = YES;
_scrollView.directionalLockEnabled = YES;
_scrollView.bounces = NO;
_scrollView.backgroundColor = [UIColor whiteColor];
CGRect frame;
frame.origin.y = 38;
frame.size.height = _scrollView.frame.size.height - 40;
frame.size.width = rect.size.width;
_pageControl = [[UIView alloc]initWithFrame:CGRectMake(0, 0, rect.size.width, 40)];
_pageNum = _views.count;
_pageControl.backgroundColor = [UIColor whiteColor];
//创建菜单按钮下划线
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, _pageControl.frame.size.height - 1, _pageControl.frame.size.width, 1)];
label.backgroundColor = [UIColor lightGrayColor];
label.tag = 200;
UILabel *selectedLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, _pageControl.frame.size.height -3, _pageControl.frame.size.width/_pageNum, 3)];
selectedLabel.backgroundColor = _tabSelectedArrowBgColor;
selectedLabel.tag = 300;
if (!_showBottomLine){
CGRect labelFrame = label.frame;
labelFrame.size.height = 0;
label.frame = labelFrame;
}
if (!_showSelectedBottomLine) {
CGRect selectedFrame = selectedLabel.frame;
selectedFrame.size.height = 0;
selectedLabel.frame = selectedFrame;
}
for (NSInteger i = 0; i < _views.count; i++) {
//创建主视图
UIView * view = [_views objectAtIndex:i];
frame.origin.x = rect.size.width * i;
[view setFrame:frame];
[_scrollView addSubview:view];
CGRect _pageframe = _pageControl.frame;
_pageframe.size.width = rect.size.width / _pageNum;
_pageframe.origin.x = _pageframe.size.width * i;
//创建菜单按钮
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:_pageframe];
button.tag = 100 + i;
[button setTitleColor:_tabTitleColor forState:UIControlStateNormal];
[button setTitleColor:_tabSelectedTitleColor forState:UIControlStateSelected];
[button setBackgroundColor:_tabBgColor];
[button setTitle:_titleArray[i] forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:15];
[button addTarget:self action:@selector(tabBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
//创建菜单右侧小图标
if (_titleIconsArray.count) {
[button setImage:_titleIconsArray[i] forState:UIControlStateNormal];
}
if (_selectedIconsArray.count) {
[button setImage:_selectedIconsArray[i] forState:UIControlStateSelected];
}
DLog(@"titleLabel.frame:x:%lf width:%lf height:%lf",button.titleLabel.frame.origin.x,button.titleLabel.frame.size.width,button.titleLabel.frame.size.height);
//创建菜单按钮右上角的小红点
UILabel *circleLabel = [[UILabel alloc] initWithFrame:CGRectMake([self getLabelWidth:_titleArray[i] fontSize:15]/2+button.titleLabel.frame.origin.x, 2, 16, 16)];
circleLabel.backgroundColor = [UIColor redColor];
circleLabel.textColor = [UIColor whiteColor];
circleLabel.font = [UIFont systemFontOfSize:12];
circleLabel.textAlignment = NSTextAlignmentCenter;
circleLabel.tag = 600 +i;
circleLabel.layer.cornerRadius = 8;
circleLabel.layer.masksToBounds = YES;
circleLabel.clipsToBounds = YES;
if (_tipsCountArray == nil || _tipsCountArray.count == 0) {
circleLabel.hidden = YES;
}else if ([_tipsCountArray[i] integerValue] == 0){
circleLabel.hidden = YES;
}else{
circleLabel.hidden = NO;
circleLabel.text = [_tipsCountArray[i] integerValue]>99?@"99+":[NSString stringWithFormat:@"%@",_tipsCountArray[i]];
CGPoint center = circleLabel.center;
CGRect cFrame = circleLabel.frame;
cFrame.size.width = [self getLabelWidth:circleLabel.text fontSize:12]+6>16?[self getLabelWidth:circleLabel.text fontSize:12]+6:16;
circleLabel.frame = cFrame;
circleLabel.center = center;
}
if (_showVLine) {
//创建中间分割线
UILabel *vlabel = [[UILabel alloc] initWithFrame:CGRectMake(-1, 10, 1, button.frame.size.height - 20)];
vlabel.backgroundColor = _tabArrowBgColor;
[button addSubview:vlabel];
if (!i) {
vlabel.hidden = YES;
}
}
if (!i) {
button.selected = YES;
}
if (button.selected) {
[UIView animateWithDuration:0.3 animations:^{
CGRect sframe = selectedLabel.frame;
sframe.origin.x = button.frame.origin.x;
selectedLabel.frame = sframe;
[button setBackgroundColor:_tabSelectedBgColor];
}];
}
[button addSubview:circleLabel];
[_pageControl addSubview:button];
}
[_pageControl addSubview:label];
[_pageControl addSubview:selectedLabel];
if (_pageNum == 1) {
_pageControl.hidden = YES;
}
if (_enabledScroll) {
[_scrollView setContentSize:CGSizeMake(rect.size.width * _views.count + 1, rect.size.height - 2)];
}else{
[_scrollView setContentSize:CGSizeZero];
}
_scrollView.delegate = self;
[self addSubview:_scrollView];
[self addSubview:_pageControl];
}
//按钮的点击事件
- (void)tabBtnClicked:(UIButton *)sender
{
NSInteger index = sender.tag - 100;
if (_showAnimation) {
[UIView beginAnimations:@"navTab" context:nil];
[UIView setAnimationDuration:0.3];
[self setSelectIndex:index];
_scrollView.contentOffset = CGPointMake(index * self.frame.size.width, 0);
[UIView commitAnimations];
}else{
[self setSelectIndex:index];
_scrollView.contentOffset = CGPointMake(index * self.frame.size.width, 0);
}
}
//设置选择的按钮索引 触发的方法
- (void)setSelectIndex:(NSInteger)index
{
if(_block){
_block(self,index);
}
_selectIndex = index;
for (NSInteger i = 0; i<_pageNum; i++) {
UIButton *btn = (UIButton *)[self viewWithTag:i + 100];
btn.backgroundColor = _tabBgColor;
btn.selected = NO;
}
UIButton *button = (UIButton *)[_pageControl viewWithTag:index + 100];
UILabel *selectedLabel = (UILabel *)[_pageControl viewWithTag:300];
button.backgroundColor = _tabSelectedBgColor;
button.selected = YES;
if (_showAnimation) {
[UIView animateWithDuration:0.3 animations:^{
CGRect frame = selectedLabel.frame;
frame.origin.x = button.frame.origin.x;
selectedLabel.frame = frame;
}];
}else{
CGRect frame = selectedLabel.frame;
frame.origin.x = button.frame.origin.x;
selectedLabel.frame = frame;
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSInteger index = scrollView.contentOffset.x/self.frame.size.width;
[self setSelectIndex:index];
}
- (void)setTabSelectedBgColor:(UIColor *)tabSelectedBgColor
{
_tabSelectedBgColor = tabSelectedBgColor;
[self setNeedsDisplay];
}
- (void)didSelectedBlock:(SelectedBlock)block
{
_block = block;
}
- (NSInteger)getLabelWidth:(NSString *)string fontSize:(CGFloat)size
{
CGSize stringSize = [string sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:size]}];
CGFloat width = stringSize.width;
return width;
}
#pragma mark - version 2.0
- (id)initWithFrame:(CGRect)frame
titles:(NSArray<NSString *> *)titles
icons:(NSArray<UIImage *> *)icons
selectedIcons:(NSArray<UIImage *> *)selectedIcons
views:(NSArray<__kindof UIView *> *)views
{
self = [super initWithFrame:frame];
if (self) {
_views = views;
_titleArray = titles;
_titleIconsArray = icons;
_selectedIconsArray = selectedIcons;
self.backgroundColor = [UIColor grayColor];
[self configSelf];
}
return self;
}
- (void)setTitleIconsArray:(NSArray<UIImage *> *)icons
selectedIconsArray:(NSArray<UIImage *> *)selectedIcons
{
_titleIconsArray = icons;
_selectedIconsArray = selectedIcons;
[self setNeedsDisplay];
}
//设置菜单标题右上角小红点上显示的数字
- (void)setTipsCountArray:(NSArray *)tips
{
_tipsCountArray = tips;
[self setNeedsDisplay];
}
@end