Untitled diff

Created Diff never expires
11 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
593 lines
11 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
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