iOS類似網(wǎng)易新聞的導(dǎo)航標(biāo)題欄

最后的效果:



結(jié)構(gòu)分析:該界面主要是有兩個(gè)UIScrollView組成,上面的UIScrollView用于存放一組帶有點(diǎn)擊手勢(shì)的UILabel(也可以是按鈕),下面的UIScrollView用于顯示對(duì)面標(biāo)題的UIViewController。
當(dāng)點(diǎn)擊上面的UILabel(或UIButton)時(shí),下面的UIScrollView就移動(dòng)到對(duì)應(yīng)的位置顯示標(biāo)題對(duì)應(yīng)的UIController的內(nèi)容。

 /**
 點(diǎn)擊上面的標(biāo)題label
 */
- (void)respondsToTitleLabel:(UITapGestureRecognizer *)tapGR {
    // 選中l(wèi)abel
    [self selectedLabel:(UILabel *)tapGR.view];

    // 顯示對(duì)應(yīng)控制器的view
    [self showContentVC:tapGR.view.tag - 200];
}

當(dāng)滑動(dòng)下面的UIScrollView顯示對(duì)應(yīng)標(biāo)題的內(nèi)容時(shí),上面的UIScrollView也移動(dòng)到對(duì)應(yīng)的位置,將該內(nèi)容對(duì)應(yīng)的UILabel(或UIButton)設(shè)為選中狀態(tài)。

#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    // 獲取當(dāng)前頁數(shù)
    CGFloat currentPage = scrollView.contentOffset.x / SCREENWIDTH;

    // 獲取當(dāng)前選中l(wèi)abel
    UILabel *currentSelectedLabel = [self.titleScrollView viewWithTag:200 + currentPage];
    // 獲取上一個(gè)選中l(wèi)abel
    UILabel *lastSelectedLabel;
    if (currentPage + 1 < self.contentVCClassArray.count - 1) {
        lastSelectedLabel = [self.titleScrollView viewWithTag:201 + currentPage];
    }

    // 計(jì)算上一個(gè)選中l(wèi)abel縮放比例
    CGFloat lastSelectedLabelScale = currentPage - (NSInteger)currentPage;
    // 計(jì)算當(dāng)前選中l(wèi)abel縮放比例
    CGFloat currentSelectedLabelScale = 1 - lastSelectedLabelScale;

    // 縮放
    currentSelectedLabel.transform = CGAffineTransformMakeScale(currentSelectedLabelScale * 0.3 + 1, currentSelectedLabelScale * 0.3 + 1);
    lastSelectedLabel.transform = CGAffineTransformMakeScale(lastSelectedLabelScale * 0.3 + 1, lastSelectedLabelScale * 0.3 + 1);

    // 顏色漸變
    currentSelectedLabel.textColor = [UIColor colorWithRed:currentSelectedLabelScale green:0 blue:0 alpha:1];
    lastSelectedLabel.textColor = [UIColor colorWithRed:lastSelectedLabelScale green:0 blue:0 alpha:1];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    // 選中l(wèi)abel
    [self selectedLabel:(UILabel *)[self.titleScrollView viewWithTag:200 + scrollView.contentOffset.x / SCREENWIDTH]];
}

屬性介紹:

@property (nonatomic, weak) UILabel *currentSelectedTitleLabel; // 當(dāng)前選中標(biāo)題Label
@property (nonatomic, strong) UIScrollView *titleScrollView;
@property (nonatomic, strong) UIScrollView *contentScrollView;

@property (nonatomic, copy) NSArray *titleArray; // 標(biāo)題數(shù)組
@property (nonatomic, copy) NSArray *contentVCClassArray; // 內(nèi)容控制器類名數(shù)組

懶加載:

#pragma mark - Getters And Setters
- (UIScrollView *)titleScrollView {
    if (!_titleScrollView) {
        _titleScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 64, SCREENWIDTH, 44)];
        _titleScrollView.contentSize = CGSizeMake(titleLabelWidth * self.contentVCClassArray.count, 0);
        // 隱藏水平滾動(dòng)條
        _titleScrollView.showsHorizontalScrollIndicator = NO;
    }
    return _titleScrollView;
}
- (UIScrollView *)contentScrollView {
    if (!_contentScrollView) {
        _contentScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(self.titleScrollView.frame), SCREENWIDTH, SCREENHEIGHT - 44)];
        _contentScrollView.contentSize = CGSizeMake(SCREENWIDTH * self.contentVCClassArray.count, 0);
        // 開啟分頁
        _contentScrollView.pagingEnabled = YES;
        // 關(guān)閉回彈
        _contentScrollView.bounces = NO;
        // 隱藏水平滾動(dòng)條
        _contentScrollView.showsHorizontalScrollIndicator = NO;
        // 設(shè)置代理
        _contentScrollView.delegate = self;
    }
    return _contentScrollView;
}

- (NSArray *)titleArray {
    if (!_titleArray) {
        _titleArray = @[@"紅", @"藍(lán)", @"綠", @"黃", @"紫", @"橘"];
    }
    return _titleArray;
}
- (NSArray *)contentVCClassArray {
    if (!_contentVCClassArray) {
        _contentVCClassArray = @[@"DBHRedViewController",
                                 @"DBHBlueViewController",
                                 @"DBHGreenViewController",
                                 @"DBHYellowViewController",
                                 @"DBHPurPleViewController",
                                 @"DBHOrangeViewController"];
    }
    return _contentVCClassArray;
}

方法介紹:

#pragma mark - Private Methods
/**
 添加所有子控制器對(duì)應(yīng)的標(biāo)題
 */
- (void)addTitleLabels {
    for (NSInteger i = 0; i < self.contentVCClassArray.count; i++) {
        UILabel *titleLabel = [[UILabel alloc] init];
        titleLabel.tag = 200 + i;
        titleLabel.frame = CGRectMake(titleLabelWidth * i, 0, titleLabelWidth, 44);
        titleLabel.text = self.titleArray[i];
        titleLabel.textAlignment = NSTextAlignmentCenter;
        titleLabel.highlightedTextColor = [UIColor redColor];
        titleLabel.userInteractionEnabled = YES;

        UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToTitleLabel:)];
        [titleLabel addGestureRecognizer:tapGR];

        // 默認(rèn)選中第1個(gè)titleLabel
        if (!i) {
            [self respondsToTitleLabel:tapGR];
        }

        [self.titleScrollView addSubview:titleLabel];
    }
}
/**
 添加所有子控制器
 */
- (void)addChildViewControllers {
    for (NSInteger i = 0; i < self.contentVCClassArray.count; i++) {
        NSString *contentVCClassName = self.contentVCClassArray[i];
        UIViewController *contentVC = [[NSClassFromString(contentVCClassName) alloc] init];
        [self addChildViewController:contentVC];

        contentVC.view.frame = CGRectMake(SCREENWIDTH * i, 0, SCREENWIDTH, SCREENHEIGHT);
        [self.contentScrollView addSubview:contentVC.view];
    }
}
/**
 選中l(wèi)abel
 */
- (void)selectedLabel:(UILabel *)label {
    // 還原前一個(gè)選中l(wèi)abel的屬性
    self.currentSelectedTitleLabel.highlighted = NO;
    self.currentSelectedTitleLabel.transform = CGAffineTransformIdentity;
    self.currentSelectedTitleLabel.textColor = [UIColor blackColor];

    // 修改選中l(wèi)abel的屬性
    label.highlighted = YES;
    label.transform = CGAffineTransformMakeScale(scale, scale);

    // 更改選中的label
    self.currentSelectedTitleLabel = label;

    // 居中選中的label
    CGFloat offsetX = label.center.x - SCREENWIDTH * 0.5;
    CGFloat maxOffsetX = self.titleScrollView.contentSize.width - SCREENWIDTH;
    if (offsetX < 0) {
        offsetX = 0;
    } else if (offsetX > maxOffsetX) {
        offsetX = maxOffsetX;
    }
    [self.titleScrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
}

/**
 顯示選中標(biāo)題對(duì)面的控制器view

 @param index 選中標(biāo)題的下標(biāo)
 */
- (void)showContentVC:(NSInteger)index {
    // 移動(dòng)內(nèi)容scrollView到指定位置
    self.contentScrollView.contentOffset = CGPointMake(SCREENWIDTH * index, 0);
}

代碼到這里就完畢了,具體使用可以參考源碼demo,這里所有的子控制器一開始就成為了當(dāng)前主控制器的子控制器。因?yàn)槲疫@里的標(biāo)簽數(shù)量比較少,所以所有子控制器的視圖當(dāng)成為子控制器的時(shí)候就已經(jīng)添加到內(nèi)容UIScrollView上面了,當(dāng)標(biāo)簽數(shù)量比較多時(shí),可以在一開始的時(shí)候只添加為子控制器,無須將子控制器的視圖加載到內(nèi)容UIScrollview上,當(dāng)需要顯示的時(shí)候再加上去以節(jié)省內(nèi)存,不過這樣的話,當(dāng)?shù)谝淮渭虞d視圖的時(shí)候會(huì)有一個(gè)明顯的空白區(qū)域,看著不大舒服。
Demo地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,844評(píng)論 4 61
  • 目錄 但還是愛,深藏于心 前情回顧 15 母親也是需要寵的 三個(gè)月之久,從未停止過想念,但也從未遇見。人群中,每一...
    盛靳閱讀 384評(píng)論 0 0
  • 暗黑和墨綠 偶有殷紅濺落 赤身裸體 面如死灰 肋骨 如卷起敗葉 枯瘦的 似深寒中待然干柴 不見光亮 黑洞讓閃爍更加...
    南倚閑坐閱讀 291評(píng)論 0 2
  • 文/冬月之戀 最近開始找北京作家劉慶邦早年寫過的一些短篇小說來看,雖然那些文章發(fā)表距今有十幾二十多年了,但在我看來...
    冬月之戀閱讀 867評(píng)論 8 25

友情鏈接更多精彩內(nèi)容