-
Notifications
You must be signed in to change notification settings - Fork 8
/
YSLContainerViewController.m
executable file
·195 lines (157 loc) · 7.75 KB
/
YSLContainerViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
//
// YSLContainerViewController.m
// YSLContainerViewController
//
// Created by yamaguchi on 2015/02/10.
// Copyright (c) 2015年 h.yamaguchi. All rights reserved.
//
#import "YSLContainerViewController.h"
#import "YSLScrollMenuView.h"
static const CGFloat kYSLScrollMenuViewHeight = 30;
@interface YSLContainerViewController () <UIScrollViewDelegate, YSLScrollMenuViewDelegate>
@property (nonatomic, assign) CGFloat topBarHeight;
@property (nonatomic, assign) NSInteger currentIndex;
@property (nonatomic, strong) YSLScrollMenuView *menuView;
@end
@implementation YSLContainerViewController
- (id)initWithControllers:(NSArray *)controllers
topBarHeight:(CGFloat)topBarHeight
parentViewController:(UIViewController *)parentViewController
{
self = [super init];
if (self) {
[parentViewController addChildViewController:self];
[self didMoveToParentViewController:parentViewController];
_topBarHeight = topBarHeight;
_titles = [[NSMutableArray alloc] init];
_childControllers = [[NSMutableArray alloc] init];
_childControllers = [controllers mutableCopy];
NSMutableArray *titles = [NSMutableArray array];
for (UIViewController *vc in _childControllers) {
[titles addObject:[vc valueForKey:@"title"]];
}
_titles = [titles mutableCopy];
}
return self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidLoad {
[super viewDidLoad];
// setupViews
UIView *viewCover = [[UIView alloc]init];
[self.view addSubview:viewCover];
// ContentScrollview setup
_contentScrollView = [[UIScrollView alloc]init];
_contentScrollView.frame = CGRectMake(0,_topBarHeight + kYSLScrollMenuViewHeight, self.view.frame.size.width, self.view.frame.size.height - (_topBarHeight + kYSLScrollMenuViewHeight));
_contentScrollView.backgroundColor = [UIColor clearColor];
_contentScrollView.pagingEnabled = YES;
_contentScrollView.delegate = self;
_contentScrollView.showsHorizontalScrollIndicator = NO;
_contentScrollView.scrollsToTop = NO;
[self.view addSubview:_contentScrollView];
_contentScrollView.contentSize = CGSizeMake(_contentScrollView.frame.size.width * self.childControllers.count, _contentScrollView.frame.size.height);
// ContentViewController setup
for (int i = 0; i < self.childControllers.count; i++) {
id obj = [self.childControllers objectAtIndex:i];
if ([obj isKindOfClass:[UIViewController class]]) {
UIViewController *controller = (UIViewController*)obj;
CGFloat scrollWidth = _contentScrollView.frame.size.width;
CGFloat scrollHeght = _contentScrollView.frame.size.height;
controller.view.frame = CGRectMake(i * scrollWidth, 0, scrollWidth, scrollHeght);
[_contentScrollView addSubview:controller.view];
}
}
// meunView
_menuView = [[YSLScrollMenuView alloc]initWithFrame:CGRectMake(0, _topBarHeight, self.view.frame.size.width, kYSLScrollMenuViewHeight)];
_menuView.backgroundColor = [UIColor clearColor];
_menuView.delegate = self;
_menuView.viewbackgroudColor = self.menuBackGroudColor;
_menuView.itemfont = self.menuItemFont;
_menuView.itemTitleColor = self.menuItemTitleColor;
_menuView.itemIndicatorColor = self.menuIndicatorColor;
_menuView.scrollView.scrollsToTop = NO;
[_menuView setItemTitleArray:self.titles];
[self.view addSubview:_menuView];
[_menuView setShadowView];
[self scrollMenuViewSelectedIndex:0];
}
#pragma mark -- private
- (void)setChildViewControllerWithCurrentIndex:(NSInteger)currentIndex
{
for (int i = 0; i < self.childControllers.count; i++) {
id obj = self.childControllers[i];
if ([obj isKindOfClass:[UIViewController class]]) {
UIViewController *controller = (UIViewController*)obj;
if (i == currentIndex) {
[controller willMoveToParentViewController:self];
[self addChildViewController:controller];
[controller didMoveToParentViewController:self];
} else {
[controller willMoveToParentViewController:self];
[controller removeFromParentViewController];
[controller didMoveToParentViewController:self];
}
}
}
}
#pragma mark -- YSLScrollMenuView Delegate
- (void)scrollMenuViewSelectedIndex:(NSInteger)index
{
[_contentScrollView setContentOffset:CGPointMake(index * _contentScrollView.frame.size.width, 0.) animated:YES];
// item color
[_menuView setItemTextColor:self.menuItemTitleColor
seletedItemTextColor:self.menuItemSelectedTitleColor
currentIndex:index];
[self setChildViewControllerWithCurrentIndex:index];
if (index == self.currentIndex) { return; }
self.currentIndex = index;
if (self.delegate && [self.delegate respondsToSelector:@selector(containerViewItemIndex:currentController:)]) {
[self.delegate containerViewItemIndex:self.currentIndex currentController:_childControllers[self.currentIndex]];
}
}
#pragma mark -- ScrollView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat oldPointX = self.currentIndex * scrollView.frame.size.width;
CGFloat ratio = (scrollView.contentOffset.x - oldPointX) / scrollView.frame.size.width;
BOOL isToNextItem = (_contentScrollView.contentOffset.x > oldPointX);
NSInteger targetIndex = (isToNextItem) ? self.currentIndex + 1 : self.currentIndex - 1;
CGFloat nextItemOffsetX = 1.0f;
CGFloat currentItemOffsetX = 1.0f;
nextItemOffsetX = (_menuView.scrollView.contentSize.width - _menuView.scrollView.frame.size.width) * targetIndex / (_menuView.itemViewArray.count - 1);
currentItemOffsetX = (_menuView.scrollView.contentSize.width - _menuView.scrollView.frame.size.width) * self.currentIndex / (_menuView.itemViewArray.count - 1);
if (targetIndex >= 0 && targetIndex < self.childControllers.count) {
// MenuView Move
CGFloat indicatorUpdateRatio = ratio;
if (isToNextItem) {
CGPoint offset = _menuView.scrollView.contentOffset;
offset.x = (nextItemOffsetX - currentItemOffsetX) * ratio + currentItemOffsetX;
[_menuView.scrollView setContentOffset:offset animated:NO];
indicatorUpdateRatio = indicatorUpdateRatio * 1;
[_menuView setIndicatorViewFrameWithRatio:indicatorUpdateRatio isNextItem:isToNextItem toIndex:self.currentIndex];
} else {
CGPoint offset = _menuView.scrollView.contentOffset;
offset.x = currentItemOffsetX - (nextItemOffsetX - currentItemOffsetX) * ratio;
[_menuView.scrollView setContentOffset:offset animated:NO];
indicatorUpdateRatio = indicatorUpdateRatio * -1;
[_menuView setIndicatorViewFrameWithRatio:indicatorUpdateRatio isNextItem:isToNextItem toIndex:targetIndex];
}
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
int currentIndex = scrollView.contentOffset.x / _contentScrollView.frame.size.width;
if (currentIndex == self.currentIndex) { return; }
self.currentIndex = currentIndex;
// item color
[_menuView setItemTextColor:self.menuItemTitleColor
seletedItemTextColor:self.menuItemSelectedTitleColor
currentIndex:currentIndex];
if (self.delegate && [self.delegate respondsToSelector:@selector(containerViewItemIndex:currentController:)]) {
[self.delegate containerViewItemIndex:self.currentIndex currentController:_childControllers[self.currentIndex]];
}
[self setChildViewControllerWithCurrentIndex:self.currentIndex];
}
@end