先看下运行效果。
主要代码部分。ViewController创建PageViewController
//
// ViewController.m
// pageViewControllerUser
//
// Created by mibo02 on 16/12/12.
// Copyright © 2016年 mibo02. All rights reserved.
//
#import "ViewController.h"
#import "SubTitleView.h"
#import "BaseViewController.h"
#import "Factory.h"
#import "Masonry.h"
#define kXMLYBGGray [UIColor colorWithRed:0.92f green:0.93f blue:0.93f alpha:1.00f]
@interface ViewController ()<UIPageViewControllerDelegate,UIPageViewControllerDataSource,SubTitleViewDelegate>
@property (weak, nonatomic) IBOutlet SubTitleView *subTitleView;
@property (nonatomic, strong)NSMutableArray *subTitleArray;
@property (nonatomic, strong)NSMutableArray *controllers;
@property (nonatomic, weak)UIPageViewController *pageViewController;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"PageViewController";
self.view.backgroundColor = kXMLYBGGray;
self.subTitleView.delegate =self;
self.subTitleView.titleArray = self.subTitleArray;
[self configSubViews];
}
- (void)configSubViews
{
[self.pageViewController.view mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.subTitleView.mas_bottom);
make.left.mas_equalTo(self.view.mas_left);
make.right.mas_equalTo(self.view.mas_right);
make.bottom.equalTo(self.view.mas_bottom).offset(-49);
}];
}
- (void)findSubTitleViewDidSelected:(SubTitleView *)titleView atIndex:(NSInteger)index title:(NSString *)title
{
[self.pageViewController setViewControllers:@[[self.controllers objectAtIndex:index]] direction:(UIPageViewControllerNavigationDirectionForward) animated:NO completion:nil];
}
#pragma mark - UIPageViewControllerDelegate/UIPageViewControllerDataSource
//这个方法是返回前一个页面,如果返回为nil,那么UIPageViewController就会认为当前页面是第一个页面不可以向前滚动或翻页
-(nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSInteger index = [self indexForViewController:viewController];
if (index == 0 || index == NSNotFound) {
return nil;
}
return [self.controllers objectAtIndex:index - 1];
}
//这个方法是下一个页面,如果返回为nil,那么UIPageViewController就会认为当前页面是最后一个页面不可以向后滚动或翻页
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSInteger index = [self indexForViewController:viewController];
if (index == NSNotFound || index == self.controllers.count - 1) {
return nil;
}
return [self.controllers objectAtIndex:index + 1];
}
//返回多少个控制器
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
return self.controllers.count;
}
#pragma mark -private
- (NSInteger)indexForViewController:(UIViewController *)controller
{
return [self.controllers indexOfObject:controller];
}
//这个方法是在UIPageViewController结束滚动或翻页的时候触发
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed
{
UIViewController *viewcontroller = self.pageViewController.viewControllers[0];
NSUInteger index = [self indexForViewController:viewcontroller];
[self.subTitleView trans2ShowAtIndex:index];
}
#pragma mark - getter
- (UIPageViewController *)pageViewController {
if(!_pageViewController) {
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithInteger:UIPageViewControllerSpineLocationNone] forKey:UIPageViewControllerOptionInterPageSpacingKey];
UIPageViewController *page = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:options];
page.delegate = self;
page.dataSource = self;
//设置UIPageViewController初始显示的页面
[page setViewControllers:@[[self.controllers firstObject]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:page];
[self.view addSubview:page.view];
_pageViewController = page;
}
return _pageViewController;
}
- (NSMutableArray *)controllers {
if(!_controllers) {
_controllers = [[NSMutableArray alloc] init];
for (NSString *title in self.subTitleArray) {
BaseViewController *con = [Factory subViewControllersWithStr:title];
[_controllers addObject:con];
}
}
return _controllers;
}
/**
* 分类标题数组
*/
- (NSMutableArray *)subTitleArray {
if(!_subTitleArray) {
_subTitleArray = [[NSMutableArray alloc] initWithObjects:@"推荐",@"分类",@"广播",@"榜单",@"主播",nil];
}
return _subTitleArray;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
封装SubTitleView
//
// SubTitleView.h
// pageViewControllerUser
//
// Created by mibo02 on 16/12/12.
// Copyright © 2016年 mibo02. All rights reserved.
//
#import <UIKit/UIKit.h>
@class SubTitleView;
@protocol SubTitleViewDelegate <NSObject>
//
- (void)findSubTitleViewDidSelected:(SubTitleView *)titleView atIndex:(NSInteger )index title:(NSString *)title;
@end
@interface SubTitleView : UIView
//字标题视图的数据源
@property (nonatomic, strong)NSMutableArray <NSString *> *titleArray;
@property (nonatomic, weak) __weak id<SubTitleViewDelegate> delegate;
- (void)trans2ShowAtIndex:(NSInteger)index;
@end
//
// SubTitleView.m
// pageViewControllerUser
//
// Created by mibo02 on 16/12/12.
// Copyright © 2016年 mibo02. All rights reserved.
//
#import "SubTitleView.h"
#import "Masonry.h"
#define kScreenWidth CGRectGetWidth([[UIScreen mainScreen] bounds]) //获取屏幕宽度
#define kScreenHeight CGRectGetHeight([[UIScreen mainScreen] bounds]) //获取屏幕高度
#define kSystemOriginColor [UIColor colorWithRed:0.96f green:0.39f blue:0.26f alpha:1.00f]
#define kSystemBlackColor [UIColor colorWithRed:0.38f green:0.39f blue:0.40f alpha:1.00f]
@interface SubTitleView ()
/**
* 滑块子视图
*/
@property (nonatomic, strong)UIView *sliderView;
//子标题按钮数组
@property (nonatomic, strong)NSMutableArray *subTitleButtonArray;
@property (nonatomic, strong)UIButton *currentSelectedButton;
@end
@implementation SubTitleView
- (instancetype)init
{
if (self = [super init]) {
self.backgroundColor = [UIColor whiteColor];
}
return self;
}
- (void)setTitleArray:(NSMutableArray<NSString *> *)titleArray
{
_titleArray = titleArray;
[self configSubTitles];
}
- (void)configSubTitles
{
//1.每一个titleView的宽度
CGFloat width = kScreenWidth / _titleArray.count;
for(NSInteger index = 0; index < _titleArray.count; index++) {
NSString *title = [_titleArray objectAtIndex:index];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:title forState:UIControlStateNormal];
[btn setTitleColor:kSystemOriginColor forState:UIControlStateSelected];
[btn setTitleColor:kSystemBlackColor forState:UIControlStateNormal];
[btn setTitleColor:kSystemOriginColor forState:UIControlStateHighlighted | UIControlStateSelected];
btn.frame = CGRectMake(width * index, 0, width, 38);
btn.titleLabel.font = [UIFont systemFontOfSize:15];
btn.adjustsImageWhenHighlighted = NO;
[btn addTarget:self action:@selector(subTitleBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.subTitleButtonArray addObject:btn];
[self addSubview:btn];
}
UIButton *firstBtn = [self.subTitleButtonArray firstObject];
[self selectedAtButton:firstBtn isFirstStart:YES];
}
//当选中了某一个按钮
- (void)selectedAtButton:(UIButton *)btn isFirstStart:(BOOL)first
{
btn.selected = YES;
self.currentSelectedButton = btn;
[self.sliderView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.mas_left).offset(btn.frame.origin.x + btn.frame.size.width / 2 - 15);
}];
if (!first) {
[UIView animateWithDuration:0.25 animations:^{
[self layoutIfNeeded];
}];
}
[self unselectedAllButton:btn];
}
//对所有按钮颜色执行反选操作
- (void)unselectedAllButton:(UIButton *)sender
{
for (UIButton *sbtn in self.subTitleButtonArray) {
if (sbtn == sender) {
continue;
}
sbtn.selected = NO;
}
}
- (void)trans2ShowAtIndex:(NSInteger)index {
if(index < 0 || index >= self.subTitleButtonArray.count) {
return;
}
UIButton *btn = [self.subTitleButtonArray objectAtIndex:index];
[self selectedAtButton:btn isFirstStart:NO];
}
//按钮点击事件回调
- (void)subTitleBtnClick:(UIButton *)btn
{
//如果点击的是当前选中的直接返回
if (btn == self.currentSelectedButton) {
return;
}
if ([self.delegate respondsToSelector:@selector(findSubTitleViewDidSelected:atIndex:title:)]) {
[self.delegate findSubTitleViewDidSelected:self atIndex:[self.subTitleButtonArray indexOfObject:btn] title:btn.titleLabel.text];
}
[self selectedAtButton:btn isFirstStart:NO];
}
#pragma mark - getter
- (NSMutableArray *)subTitleButtonArray {
if(!_subTitleButtonArray) {
_subTitleButtonArray = [[NSMutableArray alloc] init];
}
return _subTitleButtonArray;
}
//下方滑块
- (UIView *)sliderView
{
if (!_sliderView) {
UIView *view = [[UIView alloc] init];
view.backgroundColor = kSystemOriginColor;
[self addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(30, 2));
make.bottom.equalTo(self.mas_bottom);
make.left.equalTo(self.mas_left).offset(5);
}];
_sliderView = view;
}
return _sliderView;
}
@end