先看個效果圖:
上代碼:
标題欄代碼:
// 标簽欄整體
UIScrollView *titlesView = [[UIScrollView alloc] init];
titlesView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7];
titlesView.width = self.view.width;
titlesView.height = 44;
titlesView.y = 64;
titlesView.showsHorizontalScrollIndicator = NO;
titlesView.showsVerticalScrollIndicator = NO;
[self.view addSubview:titlesView];
self.titlesView = titlesView;
// 定義臨時變量
CGFloat labelW = 100;
CGFloat labelY = 0;
CGFloat labelH = self.titlesView.frame.size.height;
// 添加label
NSInteger count = self.childViewControllers.count;
for (int i = 0; i < count; i++) {
NewsTopicLabel *topicLabel = [[NewsTopicLabel alloc] init];
topicLabel.text = self.childViewControllers[i].title;
topicLabel.frame = CGRectMake(i * labelW, labelY, labelW, labelH);
[topicLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelClick:)]];
topicLabel.tag = i;
[self.titlesView addSubview:topicLabel];
if (i == 0) { // 第一個label
topicLabel.scale = 1.0;
}
}
self.titlesView.contentSize = CGSizeMake(count * labelW, 0);
下面内容代碼:
UIScrollView *contentView = [[UIScrollView alloc] init];
contentView.showsHorizontalScrollIndicator = NO;
contentView.frame = self.view.bounds;
contentView.delegate = self;
contentView.pagingEnabled = YES;
[self.view insertSubview:contentView atIndex:0];
contentView.contentSize = CGSizeMake(contentView.width * self.childViewControllers.count, 0);
self.contentView = contentView;
// 添加第一個控制器的view
[self scrollViewDidEndScrollingAnimation:contentView];
監聽label點選:
//監聽頂部label點選
- (void)labelClick:(UITapGestureRecognizer *)tap
{
// 取出被點選label的索引
NSInteger index = tap.view.tag;
// 讓底部的内容scrollView滾動到對應位置
CGPoint offset = self.contentView.contentOffset;
offset.x = index * self.contentView.frame.size.width;
[self.contentView setContentOffset:offset animated:YES];
}
核心代碼: UIScrollViewDelegate
//scrollView結束了滾動動畫以後就會調用這個方法
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
CGFloat width = scrollView.frame.size.width;
CGFloat height = scrollView.frame.size.height;
CGFloat offsetX = scrollView.contentOffset.x;
// 目前位置需要顯示的控制器的索引
NSInteger index = offsetX / width;
NewsTopicLabel * newTopicLabel = self.titlesView.subviews[index];
CGPoint titleOffset = self.titlesView.contentOffset;
titleOffset.x = newTopicLabel.center.x - width * 0.5;
// 左邊超出處理
if (titleOffset.x < 0) titleOffset.x = 0;
// 右邊超出處理
CGFloat maxTitleOffsetX = self.titlesView.contentSize.width - width;
if (titleOffset.x > maxTitleOffsetX) titleOffset.x = maxTitleOffsetX;
[self.titlesView setContentOffset:titleOffset animated:YES];
// 讓其他label回到最初的狀态
for (NewsTopicLabel *otherLabel in self.titlesView.subviews) {
if (otherLabel != newTopicLabel) otherLabel.scale = 0.0;
}
UIViewController *willShowVc = self.childViewControllers[index];
willShowVc.view.frame = CGRectMake(offsetX, 0, width, height);
// 添加控制器的view到contentScrollView中;
[scrollView addSubview:willShowVc.view];
}
//手指松開scrollView後,scrollView停止減速完畢就會調用這個
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self scrollViewDidEndScrollingAnimation:scrollView];
}
//隻要scrollView在滾動,就會調用
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat scale = scrollView.contentOffset.x / scrollView.frame.size.width;
if (scale < 0 || scale > self.titlesView.subviews.count - 1) return;
// 獲得需要操作的左邊label
NSInteger leftIndex = scale;
NewsTopicLabel *leftLabel = self.titlesView.subviews[leftIndex];
// 獲得需要操作的右邊label
NSInteger rightIndex = leftIndex + 1;
NewsTopicLabel *rightLabel = (rightIndex == self.titlesView.subviews.count) ? nil : self.titlesView.subviews[rightIndex];
// 右邊比例
CGFloat rightScale = scale - leftIndex;
// 左邊比例
CGFloat leftScale = 1 - rightScale;
// 設定label的比例
leftLabel.scale = leftScale;
rightLabel.scale = rightScale;
}
Demo位址:https://github.com/domanc/NewsController.git
轉載于:https://www.cnblogs.com/dianming/p/6668455.html