Untitled diff

Created Diff never expires
11 removals
Words removed30
Total words1581
Words removed (%)1.90
593 lines
11 additions
Words added18
Total words1569
Words added (%)1.15
593 lines
//
//
// SLPagingViewController.m
// SLPagingViewController.m
// SLPagingView
// SLPagingView
//
//
// Created by Stefan Lage on 20/11/14.
// Created by Stefan Lage on 20/11/14.
// Copyright (c) 2014 Stefan Lage. All rights reserved.
// Copyright (c) 2014 Stefan Lage. All rights reserved.
//
//


#import "SLPagingViewController.h"
#import "SLPagingViewController.h"


@interface SLPagingViewController () <UIScrollViewDelegate>
@interface SLPagingViewController () <UIScrollViewDelegate>


@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIPageControl *pageControl;
@property (nonatomic, strong) UIPageControl *pageControl;
@property (nonatomic, strong) NSMutableArray *navItemsViews;
@property (nonatomic, strong) NSMutableArray *navItemsViews;
@property (nonatomic, strong) NSMutableArray *controllerReferences;
@property (nonatomic) BOOL needToShowPageControl;
@property (nonatomic) BOOL needToShowPageControl;
@property (nonatomic) BOOL isUserInteraction;
@property (nonatomic) BOOL isUserInteraction;
@property (nonatomic) NSInteger indexSelected;
@property (nonatomic) NSInteger indexSelected;


@end
@end


@implementation SLPagingViewController
@implementation SLPagingViewController


-(id)initWithCoder:(NSCoder *)aDecoder{
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
self = [super initWithCoder:aDecoder];
if(self){
if(self){
[self initCrucialObjects:[UIColor whiteColor]
[self initCrucialObjects:[UIColor whiteColor]
showPageControl:NO];
showPageControl:NO];
}
}
return self;
return self;
}
}


#pragma mark - constructors with views
#pragma mark - constructors with views


-(id)initWithNavBarItems:(NSArray*) items views:(NSArray*)views{
-(id)initWithNavBarItems:(NSArray*) items views:(NSArray*)views{
return [self initWithNavBarItems:items
return [self initWithNavBarItems:items
navBarBackground:[UIColor whiteColor]
navBarBackground:[UIColor whiteColor]
views:views
views:views
showPageControl:YES];
showPageControl:YES];
}
}


-(id)initWithNavBarItems:(NSArray*)items views:(NSArray*)views showPageControl:(BOOL)addPageControl{
-(id)initWithNavBarItems:(NSArray*)items views:(NSArray*)views showPageControl:(BOOL)addPageControl{
return [self initWithNavBarItems:items
return [self initWithNavBarItems:items
navBarBackground:[UIColor whiteColor]
navBarBackground:[UIColor whiteColor]
views:views
views:views
showPageControl:addPageControl];
showPageControl:addPageControl];
}
}


-(id)initWithNavBarItems:(NSArray*)items navBarBackground:(UIColor*)background views:(NSArray*)views showPageControl:(BOOL)addPageControl{
-(id)initWithNavBarItems:(NSArray*)items navBarBackground:(UIColor*)background views:(NSArray*)views showPageControl:(BOOL)addPageControl{
self = [super init];
self = [super init];
if(self){
if(self){
[self initCrucialObjects:background
[self initCrucialObjects:background
showPageControl:addPageControl];
showPageControl:addPageControl];
int i = 0;
int i = 0;
for(i=0; i<items.count; i++){
for(i=0; i<items.count; i++){
// Be sure items contains only UIView's object
// Be sure items contains only UIView's object
if([[items objectAtIndex:i] isKindOfClass:UIView.class])
if([[items objectAtIndex:i] isKindOfClass:UIView.class])
[self addNavigationItem:[items objectAtIndex:i] tag:i];
[self addNavigationItem:[items objectAtIndex:i] tag:i];
}
}
// is there any controllers ?
// is there any controllers ?
if(views
if(views
&& views.count > 0){
&& views.count > 0){
NSMutableArray *controllerKeys = [NSMutableArray new];
NSMutableArray *controllerKeys = [NSMutableArray new];
for(i=0; i < views.count; i++){
for(i=0; i < views.count; i++){
if([[views objectAtIndex:i] isKindOfClass:UIView.class]){
if([[views objectAtIndex:i] isKindOfClass:UIView.class]){
UIView *ctr = [views objectAtIndex:i];
UIView *ctr = [views objectAtIndex:i];
// Set the tag
// Set the tag
ctr.tag = i;
ctr.tag = i;
[controllerKeys addObject:@(i)];
[controllerKeys addObject:@(i)];
}
}
else if([[views objectAtIndex:i] isKindOfClass:UIViewController.class]){
else if([[views objectAtIndex:i] isKindOfClass:UIViewController.class]){
UIViewController *ctr = [views objectAtIndex:i];
UIViewController *ctr = [views objectAtIndex:i];
// Set the tag
// Set the tag
ctr.view.tag = i;
ctr.view.tag = i;
[controllerKeys addObject:@(i)];
[controllerKeys addObject:@(i)];
}
}
}
}
// Number of keys equals number of controllers ?
// Number of keys equals number of controllers ?
if(controllerKeys.count == views.count)
if(controllerKeys.count == views.count)
_viewControllers = [[NSMutableDictionary alloc] initWithObjects:views
_viewControllers = [[NSMutableDictionary alloc] initWithObjects:views
forKeys:controllerKeys];
forKeys:controllerKeys];
else{
else{
// Something went wrong -> inform the client
// Something went wrong -> inform the client
NSException *exc = [[NSException alloc] initWithName:@"View Controllers error"
NSException *exc = [[NSException alloc] initWithName:@"View Controllers error"
reason:@"Some objects in viewControllers are not kind of UIViewController!"
reason:@"Some objects in viewControllers are not kind of UIViewController!"
userInfo:nil];
userInfo:nil];
@throw exc;
@throw exc;
}
}
}
}
}
}
return self;
return self;
}
}


#pragma mark - constructors with controllers
#pragma mark - constructors with controllers


-(id)initWithNavBarControllers:(NSArray *)controllers{
-(id)initWithNavBarControllers:(NSArray *)controllers{
return [self initWithNavBarControllers:controllers
return [self initWithNavBarControllers:controllers
navBarBackground:[UIColor whiteColor]
navBarBackground:[UIColor whiteColor]
showPageControl:YES];
showPageControl:YES];
}
}


-(id)initWithNavBarControllers:(NSArray *)controllers showPageControl:(BOOL)addPageControl{
-(id)initWithNavBarControllers:(NSArray *)controllers showPageControl:(BOOL)addPageControl{
return [self initWithNavBarControllers:controllers
return [self initWithNavBarControllers:controllers
navBarBackground:[UIColor whiteColor]
navBarBackground:[UIColor whiteColor]
showPageControl:addPageControl];
showPageControl:addPageControl];
}
}


-(id)initWithNavBarControllers:(NSArray *)controllers navBarBackground:(UIColor *)background showPageControl:(BOOL)addPageControl{
-(id)initWithNavBarControllers:(NSArray *)controllers navBarBackground:(UIColor *)background showPageControl:(BOOL)addPageControl{
NSMutableArray *views = [[NSMutableArray alloc] initWithCapacity:controllers.count];
NSMutableArray *views = [[NSMutableArray alloc] initWithCapacity:controllers.count];
NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:controllers.count];
NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:controllers.count];
_controllerReferences = [[NSMutableArray alloc] initWithArray:controllers];
for(int i =0; i<controllers.count; i++){
for(int i =0; i<controllers.count; i++){
// Be sure we got s subclass of UIViewController
// Be sure we got s subclass of UIViewController
if([controllers[i] isKindOfClass:UIViewController.class]){
if([controllers[i] isKindOfClass:UIViewController.class]){
UIViewController *ctr = controllers[i];
UIViewController *ctr = controllers[i];
[self addChildViewController:ctr];
[views addObject:[ctr view]];
[views addObject:[ctr view]];
// Get associated item
// Get associated item
UILabel *item = [UILabel new];
UILabel *item = [UILabel new];
[item setText:ctr.title];
[item setText:ctr.title];
[items addObject:item];
[items addObject:item];
}
}
}
}
return [self initWithNavBarItems:items
return [self initWithNavBarItems:items
navBarBackground:background
navBarBackground:background
views:views
views:views
showPageControl:addPageControl];
showPageControl:addPageControl];
}
}


#pragma mark - constructors with items & controllers
#pragma mark - constructors with items & controllers


-(id)initWithNavBarItems:(NSArray *)items controllers:(NSArray *)controllers{
-(id)initWithNavBarItems:(NSArray *)items controllers:(NSArray *)controllers{
return [self initWithNavBarItems:items
return [self initWithNavBarItems:items
navBarBackground:[UIColor whiteColor]
navBarBackground:[UIColor whiteColor]
controllers:controllers
controllers:controllers
showPageControl:YES];
showPageControl:YES];
}
}


-(id)initWithNavBarItems:(NSArray *)items controllers:(NSArray *)controllers showPageControl:(BOOL)addPageControl{
-(id)initWithNavBarItems:(NSArray *)items controllers:(NSArray *)controllers showPageControl:(BOOL)addPageControl{
return [self initWithNavBarItems:items
return [self initWithNavBarItems:items
navBarBackground:[UIColor whiteColor]
navBarBackground:[UIColor whiteColor]
controllers:controllers
controllers:controllers
showPageControl:addPageControl];
showPageControl:addPageControl];
}
}


-(id)initWithNavBarItems:(NSArray *)items navBarBackground:(UIColor *)background controllers:(NSArray *)controllers showPageControl:(BOOL)addPageControl{
-(id)initWithNavBarItems:(NSArray *)items navBarBackground:(UIColor *)background controllers:(NSArray *)controllers showPageControl:(BOOL)addPageControl{
NSMutableArray *views = [[NSMutableArray alloc] initWithCapacity:controllers.count];
NSMutableArray *views = [[NSMutableArray alloc] initWithCapacity:controllers.count];
_controllerReferences = [[NSMutableArray alloc] initWithArray:controllers];
for(int i =0; i<controllers.count; i++){
for(int i =0; i<controllers.count; i++){
// Be sure we got s subclass of UIViewController
// Be sure we got s subclass of UIViewController
if([controllers[i] isKindOfClass:UIViewController.class])
if([controllers[i] isKindOfClass:UIViewController.class]){
[self addChildViewController:controllers[i]];
[views addObject:[(UIViewController*)controllers[i] view]];
[views addObject:[(UIViewController*)controllers[i] view]];
}
}
}
return [self initWithNavBarItems:items
return [self initWithNavBarItems:items
navBarBackground:background
navBarBackground:background
views:views
views:views
showPageControl:addPageControl];
showPageControl:addPageControl];
}
}


#pragma mark - LifeCycle
#pragma mark - LifeCycle


- (void)loadView {
- (void)loadView {
[super loadView];
[super loadView];
// Notify all conctrollers
// Notify all conctrollers
[self notifyControllers:NSSelectorFromString(@"loadView")
[self notifyControllers:NSSelectorFromString(@"loadView")
object:nil
object:nil
checkIndex:NO];
checkIndex:NO];
// Try to load controller from storyboard
// Try to load controller from storyboard
[self loadStoryboardControllers];
[self loadStoryboardControllers];
// Set up the controller
// Set up the controller
[self setupPagingProcess];
[self setupPagingProcess];
}
}


-(void)viewWillAppear:(BOOL)animated{
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[super viewWillAppear:animated];
// Be notify when the device's orientation change
// Be notify when the device's orientation change
[[NSNotificationCenter defaultCenter] addObserver:self
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(orientationChanged:)
selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
name:UIDeviceOrientationDidChangeNotification
object:nil];
object:nil];
// Notify all conctrollers
// Notify all conctrollers
[self notifyControllers:NSSelectorFromString(@"viewDidAppear:")
[self notifyControllers:NSSelectorFromString(@"viewDidAppear:")
object:@(animated)
object:@(animated)
checkIndex:YES];
checkIndex:YES];
[self.navigationController.navigationBar addSubview:self.navigationBarView];
}
}


-(void)viewDidAppear:(BOOL)animated{
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[super viewDidAppear:animated];
// Notify all conctrollers
// Notify all conctrollers
[self notifyControllers:NSSelectorFromString(@"viewDidAppear:")
[self notifyControllers:NSSelectorFromString(@"viewDidAppear:")
object:@(animated)
object:@(animated)
checkIndex:YES];
checkIndex:YES];
}
}


-(void)viewWillDisappear:(BOOL)animated{
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[super viewWillDisappear:animated];
// Notify all conctrollers
// Notify all conctrollers
[self notifyControllers:NSSelectorFromString(@"viewWillDisappear:")
[self notifyControllers:NSSelectorFromString(@"viewWillDisappear:")
object:@(animated)
object:@(animated)
checkIndex:YES];
checkIndex:YES];
[self.navigationBarView removeFromSuperview];
}
}


- (void)viewDidLoad{
- (void)viewDidLoad{
[super viewDidLoad];
[super viewDidLoad];
// Notify all conctrollers
// Notify all conctrollers
[self notifyControllers:NSSelectorFromString(@"viewDidLoad")
[self notifyControllers:NSSelectorFromString(@"viewDidLoad")
object:nil
object:nil
checkIndex:NO];
checkIndex:NO];
[self setCurrentIndex:self.indexSelected
[self setCurrentIndex:self.indexSelected
animated:NO];
animated:NO];
}
}


-(void)dealloc{
-(void)dealloc{
// Remove Observers
// Remove Observers
[[NSNotificationCenter defaultCenter]removeObserver:self
[[NSNotificationCenter defaultCenter]removeObserver:self
forKeyPath:UIDeviceOrientationDidChangeNotification];
forKeyPath:UIDeviceOrientationDidChangeNotification];
// Close relationships
// Close relationships
_didChangedPage = nil;
_didChangedPage = nil;
_pagingViewMoving = nil;
_pagingViewMoving = nil;
_pagingViewMovingRedefine = nil;
_pagingViewMovingRedefine = nil;
}
}


- (void)didReceiveMemoryWarning{
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
// Dispose of any resources that can be recreated.
}
}


- (void)viewWillLayoutSubviews {
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[super viewWillLayoutSubviews];
self.navigationBarView.frame = (CGRect){0, 0, SCREEN_SIZE.width, 44};
self.navigationBarView.frame = (CGRect){0, 0, SCREEN_SIZE.width, 44};
}
}


#pragma mark - public methods
#pragma mark - public methods


-(void)updateUserInteractionOnNavigation:(BOOL)activate{
-(void)updateUserInteractionOnNavigation:(BOOL)activate{
self.isUserInteraction = activate;
self.isUserInteraction = activate;
}
}


-(void)setCurrentIndex:(NSInteger)index animated:(BOOL)animated{
-(void)setCurrentIndex:(NSInteger)index animated:(BOOL)animated{
// Be sure we got an existing index
// Be sure we got an existing index
if(index < 0 || index > self.navigationBarView.subviews.count-1){
if(index < 0 || index > self.navigationBarView.subviews.count-1){
NSException *exc = [[NSException alloc] initWithName:@"Index out of range"
NSException *exc = [[NSException alloc] initWithName:@"Index out of range"
reason:@"The index is out of range of subviews's count!"
reason:@"The index is out of range of subviews's count!"
userInfo:nil];
userInfo:nil];
@throw exc;
@throw exc;
}
}
// save current index
// save current index
self.indexSelected = index;
self.indexSelected = index;
// Get the right position and update it
// Get the right position and update it
CGFloat xOffset = (index * ((int)SCREEN_SIZE.width));
CGFloat xOffset = (index * ((int)SCREEN_SIZE.width));
[self.scrollView setContentOffset:CGPointMake(xOffset, self.scrollView.contentOffset.y) animated:animated];
[self.scrollView setContentOffset:CGPointMake(xOffset, self.scrollView.contentOffset.y) animated:animated];
}
}


-(void)addViewControllers:(UIViewController *) controller needToRefresh:(BOOL) refresh{
-(void)addViewControllers:(UIViewController *) controller needToRefresh:(BOOL) refresh{
int tag = (int)self.viewControllers.count;
int tag = (int)self.viewControllers.count;
// Try to get a navigation item
// Try to get a navigation item
UIView *v = nil;
UIView *v = nil;
if(controller.title){
if(controller.title){
UILabel *item = [UILabel new];
UILabel *item = [UILabel new];
[item setText:controller.title];
[item setText:controller.title];
v = item;
v = item;
}
}
else if(controller.navigationItem && controller.navigationItem.titleView){
else if(controller.navigationItem && controller.navigationItem.titleView){
v = controller.navigationItem.titleView;
v = controller.navigationItem.titleView;
}
}
else{
else{
UILabel *item = [UILabel new];
UILabel *item = [UILabel new];
[item setText:NSStringFromClass(controller.class)];
[item setText:NSStringFromClass(controller.class)];
v = item;
v = item;
}
}
// Adds a navigation item
// Adds a navigation item
[self addNavigationItem:v
[self addNavigationItem:v
tag:tag];
tag:tag];
// Save the controller
// Save the controller
[self.viewControllers setObject:controller.view
[self.viewControllers setObject:controller.view
forKey:@(tag)];
forKey:@(tag)];
// Save controller reference
// Update controller's hierarchy
[self.controllerReferences addObject:controller];
[self addChildViewController:controller];
// Do we need to refresh the UI ?
// Do we need to refresh the UI ?
if(refresh)
if(refresh)
[self setupPagingProcess];
[self setupPagingProcess];
}
}


-(void)setNavigationBarColor:(UIColor*) color{
-(void)setNavigationBarColor:(UIColor*) color{
if(color)
if(color)
self.navigationBarView.backgroundColor = color;
self.navigationBarView.backgroundColor = color;
}
}


#pragma mark - Internal methods
#pragma mark - Internal methods


-(void) initCrucialObjects:(UIColor *)background showPageControl:(BOOL) showPageControl{
-(void) initCrucialObjects:(UIColor *)background showPageControl:(BOOL) showPageControl{
_needToShowPageControl = showPageControl;
_needToShowPageControl = showPageControl;
_navigationBarView = [[UIView alloc] init];
_navigationBarView = [[UIView alloc] init];
_navigationBarView.backgroundColor = background;
_navigationBarView.backgroundColor = background;
// UserInteraction activate by default
// UserInteraction activate by default
_isUserInteraction = YES;
_isUserInteraction = YES;
// Default value for the navigation style
// Default value for the navigation style
_navigationSideItemsStyle = SLNavigationSideItemsStyleDefault;
_navigationSideItemsStyle = SLNavigationSideItemsStyleDefault;
_viewControllers = [NSMutableDictionary new];
_viewControllers = [NSMutableDictionary new];
_navItemsViews = [NSMutableArray new];
_navItemsViews = [NSMutableArray new];
_controllerReferences = [NSMutableArray new];
}
}


// Load any defined controllers from the storyboard
// Load any defined controllers from the storyboard
- (void)loadStoryboardControllers
- (void)loadStoryboardControllers
{
{
if (self.storyboard)
if (self.storyboard)
{
{
BOOL isThereNextIdentifier = YES;
BOOL isThereNextIdentifier = YES;
int idx = 0;
int idx = 0;
while (isThereNextIdentifier) {
while (isThereNextIdentifier) {
@try
@try
{
{
[self performSegueWithIdentifier:[NSString stringWithFormat:@"%@%d", SLPagingViewPrefixIdentifier, idx]
[self performSegueWithIdentifier:[NSString stringWithFormat:@"%@%d", SLPagingViewPrefixIdentifier, idx]
sender:nil];
sender:nil];
idx++;
idx++;
}
}
@catch(NSException *exception) {
@catch(NSException *exception) {
isThereNextIdentifier = NO;
isThereNextIdentifier = NO;
}
}
}
}
if(self.navigationController && self.navigationController.navigationBar)
if(self.navigationController && self.navigationController.navigationBar)
_navigationBarView.backgroundColor = self.navigationController.navigationBar.backgroundColor;
_navigationBarView.backgroundColor = self.navigationController.navigationBar.backgroundColor;
}
}
}
}


// Perform a specific selector for each controllers
// Perform a specific selector for each controllers
-(void)notifyControllers:(SEL)selector object:(id)object checkIndex:(BOOL)index{
-(void)notifyControllers:(SEL)selector object:(id)object checkIndex:(BOOL)index{
if(index && self.controllerReferences.count > self.indexSelected) {
if(index && self.childViewControllers.count > self.indexSelected) {
[(UIViewController*)self.controllerReferences[self.indexSelected] performSelectorOnMainThread:selector
[(UIViewController*)self.childViewControllers[self.indexSelected] performSelectorOnMainThread:selector
withObject:object
withObject:object
waitUntilDone:NO];
waitUntilDone:NO];
}
}
else{
else{
[self.controllerReferences enumerateObjectsUsingBlock:^(UIViewController* ctr, NSUInteger idx, BOOL *stop) {
[self.childViewControllers enumerateObjectsUsingBlock:^(UIViewController* ctr, NSUInteger idx, BOOL *stop) {
[ctr performSelectorOnMainThread:selector
[ctr performSelectorOnMainThread:selector
withObject:object
withObject:object
waitUntilDone:NO];
waitUntilDone:NO];
}];
}];
}
}
}
}


// Add a view as a navigationBarItem
// Add a view as a navigationBarItem
-(void)addNavigationItem:(UIView*)v tag:(int)tag{
-(void)addNavigationItem:(UIView*)v tag:(int)tag{
CGFloat distance = (SCREEN_SIZE.width/2) - self.navigationSideItemsStyle;
CGFloat distance = (SCREEN_SIZE.width/2) - self.navigationSideItemsStyle;
CGSize vSize = ([v isKindOfClass:[UILabel class]])? [self getLabelSize:(UILabel*)v] : v.frame.size;
CGSize vSize = ([v isKindOfClass:[UILabel class]])? [self getLabelSize:(UILabel*)v] : v.frame.size;
CGFloat originX = (SCREEN_SIZE.width/2 - vSize.width/2) + self.navItemsViews.count*distance;
CGFloat originX = (SCREEN_SIZE.width/2 - vSize.width/2) + self.navItemsViews.count*distance;
v.frame = (CGRect){originX, 8, vSize.width, vSize.height};
v.frame = (CGRect){originX, 8, vSize.width, vSize.height};
v.tag = tag;
v.tag = tag;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(tapOnHeader:)];
action:@selector(tapOnHeader:)];
[v addGestureRecognizer:tap];
[v addGestureRecognizer:tap];
[v setUserInteractionEnabled:YES];
[v setUserInteractionEnabled:YES];
[_navigationBarView addSubview:v];
[_navigationBarView addSubview:v];
if(!_navItemsViews)
if(!_navItemsViews)
_navItemsViews = [[NSMutableArray alloc] init];
_navItemsViews = [[NSMutableArray alloc] init];
[_navItemsViews addObject:v];
[_navItemsViews addObject:v];
}
}


-(void)setupPagingProcess{
-(void)setupPagingProcess{
// Make our ScrollView
// Make our ScrollView
CGRect frame = CGRectMake(0, 0, SCREEN_SIZE.width, self.view.bounds.size.height);
CGRect frame = CGRectMake(0, 0, SCREEN_SIZE.width, self.view.bounds.size.height);
self.scrollView = [[UIScrollView alloc] initWithFrame:frame];
self.scrollView = [[UIScrollView alloc] initWithFrame:frame];
self.scrollView.backgroundColor = [UIColor clearColor];
self.scrollView.backgroundColor = [UIColor clearColor];
self.scrollView.pagingEnabled = YES;
self.scrollView.pagingEnabled = YES;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.showsVerticalScrollIndicator = NO;
self.scrollView.showsVerticalScrollIndicator = NO;
self.scrollView.delegate = self;
self.scrollView.delegate = self;
self.scrollView.bounces = NO;
self.scrollView.bounces = NO;
[self.scrollView setContentInset:UIEdgeInsetsMake(0, 0, -80, 0)];
[self.scrollView setContentInset:UIEdgeInsetsMake(0, 0, -80, 0)];
[self.view addSubview:self.scrollView];
[self.view addSubview:self.scrollView];
// Adds all views
// Adds all views
[self addControllers];
[self addControllers];
if(self.needToShowPageControl){
if(self.needToShowPageControl){
// Make the page control
// Make the page control
self.pageControl = [[UIPageControl alloc] init];
self.pageControl = [[UIPageControl alloc] init];
self.pageControl.frame = (CGRect){0, 35, 0, 0};
self.pageControl.frame = (CGRect){0, 35, 0, 0};
self.pageControl.numberOfPages = self.navigationBarView.subviews.count;
self.pageControl.numberOfPages = self.navigationBarView.subviews.count;
self.pageControl.currentPage = 0;
self.pageControl.currentPage = 0;
if(self.currentPageControlColor) self.pageControl.currentPageIndicatorTintColor = self.currentPageControlColor;
if(self.currentPageControlColor) self.pageControl.currentPageIndicatorTintColor = self.currentPageControlColor;
if(self.tintPageControlColor) self.pageControl.pageIndicatorTintColor = self.tintPageControlColor;
if(self.tintPageControlColor) self.pageControl.pageIndicatorTintColor = self.tintPageControlColor;
[self.navigationBarView addSubview:self.pageControl];
[self.navigationBarView addSubview:self.pageControl];
}
}
[self.navigationController.navigationBar addSubview:self.navigationBarView];
}
}


// Add all views
// Add all views
-(void)addControllers{
-(void)addControllers{
if(self.viewControllers
if(self.viewControllers
&& self.viewControllers.count > 0){
&& self.viewControllers.count > 0){
float width = SCREEN_SIZE.width * self.viewControllers.count;
float width = SCREEN_SIZE.width * self.viewControllers.count;
float height = CGRectGetHeight(self.view.bounds) - CGRectGetHeight(self.navigationBarView.bounds);
float height = CGRectGetHeight(self.view.bounds) - CGRectGetHeight(self.navigationBarView.bounds);
self.scrollView.contentSize = (CGSize){width, height};
self.scrollView.contentSize = (CGSize){width, height};
__block int i = 0;
__block int i = 0;
// Sort all keys in ascending
// Sort all keys in ascending
NSArray *sortedIndexes = [self.viewControllers.allKeys sortedArrayUsingComparator:^NSComparisonResult(NSNumber *key1, NSNumber *key2) {
NSArray *sortedIndexes = [self.viewControllers.allKeys sortedArrayUsingComparator:^NSComparisonResult(NSNumber *key1, NSNumber *key2) {
if ([key1 integerValue] > [key2 integerValue]) {
if ([key1 integerValue] > [key2 integerValue]) {
return (NSComparisonResult)NSOrderedDescending;
return (NSComparisonResult)NSOrderedDescending;
}
}
if ([key1 integerValue] < [key2 integerValue]) {
if ([key1 integerValue] < [key2 integerValue]) {
return (NSComparisonResult)NSOrderedAscending;
return (NSComparisonResult)NSOrderedAscending;
}
}
return (NSComparisonResult)NSOrderedSame;
return (NSComparisonResult)NSOrderedSame;
}];
}];


[sortedIndexes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[sortedIndexes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UIView *v = self.viewControllers[@(idx)];
UIView *v = self.viewControllers[@(idx)];
[self.scrollView addSubview:v];
[self.scrollView addSubview:v];
if([self useAutoLayout:v]){
if([self useAutoLayout:v]){
// Using AutoLayout
// Using AutoLayout
v.translatesAutoresizingMaskIntoConstraints = NO;
v.translatesAutoresizingMaskIntoConstraints = NO;
// Width constraint, half of parent view width
// Width constraint, half of parent view width
[self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:v
[self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:v
attribute:NSLayoutAttributeWidth
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
relatedBy:NSLayoutRelationEqual
toItem:self.scrollView
toItem:self.scrollView
attribute:NSLayoutAttributeWidth
attribute:NSLayoutAttributeWidth
multiplier:1.0
multiplier:1.0
constant:0]];
constant:0]];
// Height constraint, half of parent view height
// Height constraint, half of parent view height
[self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:v
[self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:v
attribute:NSLayoutAttributeHeight
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
relatedBy:NSLayoutRelationEqual
toItem:self.scrollView
toItem:self.scrollView
attribute:NSLayoutAttributeHeight
attribute:NSLayoutAttributeHeight
multiplier:1.0
multiplier:1.0
constant:0]];
constant:0]];
UIView *previous = [self.viewControllers objectForKey:[NSNumber numberWithFloat:(idx - 1)]];
UIView *previous = [self.viewControllers objectForKey:[NSNumber numberWithFloat:(idx - 1)]];
if(previous)
if(previous)
// Distance constraint: set distance between previous view and the current one
// Distance constraint: set distance between previous view and the current one
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[previous]-0-[v]"
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[previous]-0-[v]"
options:0
options:0
metrics:nil
metrics:nil
views:@{@"v" : v, @"previous" : previous}]];
views:@{@"v" : v, @"previous" : previous}]];
else
else
// First view
// First view
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[v]"
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[v]"
options:0
options:0
metrics:nil
metrics:nil
views:@{@"v" : v }]];
views:@{@"v" : v }]];
// Oridnate constraint : set the space between the Top and the current view
// Oridnate constraint : set the space between the Top and the current view
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:|-%f-[v]", CGRectGetHeight(self.navigationBarView.frame)]
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:|-%f-[v]", CGRectGetHeight(self.navigationBarView.frame)]
options:0
options:0
metrics:nil
metrics:nil
views:@{@"v" : v}]];
views:@{@"v" : v}]];
}
}
else{
else{
v.frame = (CGRect){SCREEN_SIZE.width * i, 0, SCREEN_SIZE.width, CGRectGetHeight(self.view.frame)};
v.frame = (CGRect){SCREEN_SIZE.width * i, 0, SCREEN_SIZE.width, CGRectGetHeight(self.view.frame)};
i++;
i++;
}
}
}];
}];
}
}
}
}


// Scroll to the view tapped
// Scroll to the view tapped
-(void)tapOnHeader:(UITapGestureRecognizer *)recognizer{
-(void)tapOnHeader:(UITapGestureRecognizer *)recognizer{
if(self.isUserInteraction){
if(self.isUserInteraction){
// Get the wanted view
// Get the wanted view
UIView *view = [self.viewControllers objectForKey:@(recognizer.view.tag)];
UIView *view = [self.viewControllers objectForKey:@(recognizer.view.tag)];
[self.scrollView scrollRectToVisible:view.frame
[self.scrollView scrollRectToVisible:view.frame
animated:YES];
animated:YES];
}
}
}
}


-(CGSize) getLabelSize:(UILabel *)lbl{
-(CGSize) getLabelSize:(UILabel *)lbl{
return [[lbl text] sizeWithAttributes:@{NSFontAttributeName:[lbl font]}];;
return [[lbl text] sizeWithAttributes:@{NSFontAttributeName:[lbl font]}];;
}
}


/**
/**
* Check whether the app use Auto Layout
* Check whether the app use Auto Layout
*/
*/
-(BOOL)useAutoLayout:(UIView*)someView{
-(BOOL)useAutoLayout:(UIView*)someView{
return someView.constraints.count;
return someView.constraints.count;
}
}


#pragma mark - Internal Methods
#pragma mark - Internal Methods
#pragma mark - Views management
#pragma mark - Views management


/* Update all nav items frame
/* Update all nav items frame
*
*
* @param xOffset, abscissa of the scrollview's contentOffset
* @param xOffset, abscissa of the scrollview's contentOffset
*/
*/
-(void)updateNavItems:(CGFloat) xOffset{
-(void)updateNavItems:(CGFloat) xOffset{
__block int i = 0;
__block int i = 0;
[self.navItemsViews enumerateObjectsUsingBlock:^(UIView* v, NSUInteger idx, BOOL *stop) {
[self.navItemsViews enumerateObjectsUsingBlock:^(UIView* v, NSUInteger idx, BOOL *stop) {
CGFloat distance = (SCREEN_SIZE.width/2) - self.navigationSideItemsStyle;
CGFloat distance = (SCREEN_SIZE.width/2) - self.navigationSideItemsStyle;
CGSize vSize = ([v isKindOfClass:[UILabel class]])? [self getLabelSize:(UILabel*)v] : v.frame.size;
CGSize vSize = ([v isKindOfClass:[UILabel class]])? [self getLabelSize:(UILabel*)v] : v.frame.size;
CGFloat originX = ((SCREEN_SIZE.width/2 - vSize.width/2) + i*distance) - xOffset/(SCREEN_SIZE.width/distance);
CGFloat originX = ((SCREEN_SIZE.width/2 - vSize.width/2) + i*distance) - xOffset/(SCREEN_SIZE.width/distance);
v.frame = (CGRect){originX, 8, vSize.width, vSize.height};
v.frame = (CGRect){originX, 8, vSize.width, vSize.height};
i++;
i++;
}];
}];
}
}


// Adapt all views the main screen
// Adapt all views the main screen
-(void)adaptViews{
-(void)adaptViews{
// Update the nav items + the scrollview
// Update the nav items + the scrollview
[self updateNavItems:self.scrollView.contentOffset.x];
[self updateNavItems:self.scrollView.contentOffset.x];
// Be sure to stay on the same view
// Be sure to stay on the same view
[self setCurrentIndex:self.indexSelected
[self setCurrentIndex:self.indexSelected
animated:NO];
animated:NO];
[self.scrollView setNeedsUpdateConstraints];
[self.scrollView setNeedsUpdateConstraints];
[self.view setNeedsUpdateConstraints];
[self.view setNeedsUpdateConstraints];
}
}


#pragma mark - Internal Methods
#pragma mark - Internal Methods
#pragma mark - Notifications
#pragma mark - Notifications


// Call when the screen orientation is updated
// Call when the screen orientation is updated
- (void)orientationChanged:(NSNotification *)notification{
- (void)orientationChanged:(NSNotification *)notification{
[self adaptViews];
[self adaptViews];
}
}


#pragma mark - SLPagingViewDidChanged delegate
#pragma mark - SLPagingViewDidChanged delegate


-(void)sendNewIndex:(UIScrollView *)scrollView{
-(void)sendNewIndex:(UIScrollView *)scrollView{
CGFloat xOffset = scrollView.contentOffset.x;
CGFloat xOffset = scrollView.contentOffset.x;
NSInteger oldIndex = self.indexSelected;
NSInteger oldIndex = self.indexSelected;
self.indexSelected = ((int) roundf(xOffset) % (self.navigationBarView.subviews.count * (int)SCREEN_SIZE.width)) / SCREEN_SIZE.width;
self.indexSelected = ((int) roundf(xOffset) % (self.navigationBarView.subviews.count * (int)SCREEN_SIZE.width)) / SCREEN_SIZE.width;
if(oldIndex != self.indexSelected)
if(oldIndex != self.indexSelected)
[self notifyControllers:NSSelectorFromString(@"viewDidDisappear:")
[self notifyControllers:NSSelectorFromString(@"viewDidDisappear:")
object:@(YES)
object:@(YES)
checkIndex:YES];
checkIndex:YES];
if(self.pageControl){
if(self.pageControl){
if (self.pageControl.currentPage != self.indexSelected)
if (self.pageControl.currentPage != self.indexSelected)
{
{
self.pageControl.currentPage = self.indexSelected;
self.pageControl.currentPage = self.indexSelected;
if(self.didChangedPage)
if(self.didChangedPage)
self.didChangedPage(self.indexSelected);
self.didChangedPage(self.indexSelected);
}
}
}
}
else{
else{
if(self.didChangedPage)
if(self.didChangedPage)
self.didChangedPage(self.indexSelected);
self.didChangedPage(self.indexSelected);
}
}
// Try to notify the controller concerned
// Try to notify the controller concerned
[self notifyControllers:NSSelectorFromString(@"viewDidAppear:")
[self notifyControllers:NSSelectorFromString(@"viewDidAppear:")
object:@(YES)
object:@(YES)
checkIndex:YES];
checkIndex:YES];
}
}


#pragma mark - ScrollView delegate
#pragma mark - ScrollView delegate


-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
// Try to notify the controller concerned
// Try to notify the controller concerned
[self notifyControllers:NSSelectorFromString(@"viewWillDisappear:")
[self notifyControllers:NSSelectorFromString(@"viewWillDisappear:")
object:@(YES)
object:@(YES)
checkIndex:YES
checkIndex:YES
];
];
}
}


- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// Update nav items
// Update nav items
[self updateNavItems:scrollView.contentOffset.x];
[self updateNavItems:scrollView.contentOffset.x];
if(self.pagingViewMoving)
if(self.pagingViewMoving)
// Customize the navigation items
// Customize the navigation items
self.pagingViewMoving(self.navItemsViews);
self.pagingViewMoving(self.navItemsViews);
if(self.pagingViewMovingRedefine)
if(self.pagingViewMovingRedefine)
// Wants to redefine all behaviors
// Wants to redefine all behaviors
self.pagingViewMovingRedefine(scrollView, self.navItemsViews);
self.pagingViewMovingRedefine(scrollView, self.navItemsViews);
}
}


- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[self sendNewIndex:scrollView];
[self sendNewIndex:scrollView];
}
}
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
[self sendNewIndex:scrollView];
[self sendNewIndex:scrollView];
}
}


@end
@end


#pragma mark - SLPagingViewControllerSegueSetController segue identifier's prefix
#pragma mark - SLPagingViewControllerSegueSetController segue identifier's prefix


NSString * const SLPagingViewPrefixIdentifier = @"sl_";
NSString * const SLPagingViewPrefixIdentifier = @"sl_";


#pragma mark - SLPagingViewControllerSegueSetController class
#pragma mark - SLPagingViewControllerSegueSetController class


@implementation SLPagingViewControllerSegueSetController
@implementation SLPagingViewControllerSegueSetController


-(void)perform{
-(void)perform{
// Get SLPagingViewController (sourceViewController)
// Get SLPagingViewController (sourceViewController)
SLPagingViewController *src = self.sourceViewController;
SLPagingViewController *src = self.sourceViewController;
// Add it to the subviews
// Add it to the subviews
if(self.destinationViewController)
if(self.destinationViewController)
[src addViewControllers:self.destinationViewController
[src addViewControllers:self.destinationViewController
needToRefresh:NO];
needToRefresh:NO];
}
}


@end
@end