天天看點

仿網易新聞标題欄

先看個效果圖:

仿網易新聞标題欄

上代碼:

标題欄代碼:

// 标簽欄整體
    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

git