iOS 自定義UINavigationController+UIScrollView聯(lián)動

上一章講解了自定義tabBar,本章講解怎樣簡單的自定義UINavigationController以及UIScrollView滑動頁面的聯(lián)動。

一、設(shè)置導(dǎo)航欄背景顏色

確保當(dāng)前控制器已擁有導(dǎo)航欄

self.navigationController.navigationBar.barTintColor = JHRGB(76, 201, 245);   

二、設(shè)置左右item

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"global_search"] style:UIBarButtonItemStyleDone target:nil action:nil];   

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"title_button_more"] style:UIBarButtonItemStyleDone target:nil action:nil];   
此時效果圖
nav0.png
可以看到item的圖片被渲染了,可以使用tintColor設(shè)置控件顏色
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];   
此時效果圖
nav1.png

三、創(chuàng)建ScrollView

//這里為了方便我是直接用的storyboard
@property (weak, nonatomic) IBOutlet UIScrollView *contentScrollView;   
  • 引入子控制器
NSArray * vcName = @[@"JHLeftVC",@"JHMiddleVC",@"JHRightVC"];
    for (NSInteger i=0; i<vcName.count; i++) {
        
        NSString *vcNameStr = vcName[I];
        
        UIViewController * vc = [[NSClassFromString(vcNameStr) alloc]init];
        vc.title = self.dataList[I];
        [self addChildViewController:vc];
    }   
  • 設(shè)置contentScrollView
 //設(shè)置scrollView的contentSize
    self.contentScrollView.contentSize = CGSizeMake(SCREEN_WIDTH * self.dataList.count, 0);
    
    self.contentScrollView.delegate = self;
    self.contentScrollView.pagingEnabled = YES;
    //默認(rèn)先展示第二個界面
    self.contentScrollView.contentOffset = CGPointMake(SCREEN_WIDTH, 0);
    
    //進(jìn)入主控制器時加載頁面
    [self scrollViewDidEndScrollingAnimation:self.contentScrollView];   
  • 設(shè)置代理方法
#pragma mark --- UIScrollViewDelegate
//減速結(jié)束時調(diào)用。加載子控制器view
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    CGFloat width = SCREEN_WIDTH;
    CGFloat height = SCREEN_HEIGHT;
    CGFloat offset = scrollView.contentOffset.x;
    
    //獲取第幾個  的索引值
    NSInteger idx = offset / width;
    
    //根據(jù)索引值,返回vc的引用
    UIViewController * vc = self.childViewControllers[idx];
    
    //判讀當(dāng)前vc是否執(zhí)行過viewDidLoad
    if ([vc isViewLoaded]) return;
    
    //設(shè)置子控制器view的大小
    vc.view.frame = CGRectMake(offset, 0, width, height);
    
    //將子控制器view加入到scrollView上
    [scrollView addSubview:vc.view];
}   
此時的效果圖
scrollView0.gif

四、自定義topView[navigationItem.titleView]

  • 創(chuàng)建topView替換navigationItem.titleView

  • 定義方法-(instancetype)initWithFrame:(CGRect)frame titleNames:(NSArray *)titles;

  • 定義屬性

/** topView的按鈕 */
@property (nonatomic, strong) NSMutableArray * buttons;
/** topView按鈕下的線條 */
@property (nonatomic, strong)UIView *lineView;   
  • 懶加載buttons
-(NSArray *)buttons{
    if (!_buttons) {
        _buttons = [NSMutableArray array];
    }
    return _buttons;
}   
  • 實現(xiàn)方法
-(instancetype)initWithFrame:(CGRect)frame titleNames:(NSArray *)titles{
    self = [super initWithFrame:frame];
    if (self) {
        
        CGFloat btnW = self.frame.size.width/titles.count;
        CGFloat btnH = self.frame.size.height;
        
        for (NSInteger i=0; i<titles.count; i++) {
            UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
            NSString * vcTitle = titles[I];
            [button setTitle:vcTitle forState:UIControlStateNormal];
            
            [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
            
            button.titleLabel.font = [UIFont systemFontOfSize:18];
            
            button.frame = CGRectMake(i*btnW, 0, btnW, btnH);
            
            [button addTarget:self action:@selector(clickTitle:) forControlEvents:UIControlEventTouchUpInside];
            
            button.tag = i;//設(shè)置block的回傳
            
            [self addSubview:button];
            
            [self.buttons addObject:button];
            
        }
    }
    return self;
}   

//topView的button點擊事件
-(void)clickTitle:(UIButton *)button{
    
}   
   
  • 在之前的VC中導(dǎo)入頭文件[這個類里我使用了YYKit]
#import "JHTopView.h"   
  • 創(chuàng)建topView屬性
@property (nonatomic, strong) JHTopView * topView;   

-(JHTopView *)topView{
    if (!_topView) {
        _topView = [[JHTopView alloc]initWithFrame:CGRectMake(0, 0, 200, 50) titleNames:self.dataList];
        };
    }
    return _topView;
}   
  • 替換navigationItem.titleView
self.navigationItem.titleView = self.topView;   
此時效果圖
topView1.png

五、設(shè)置lineView

if (i == 1) {
                CGFloat h = 2;
                CGFloat y = 40;
                
                [button.titleLabel sizeToFit];
                
                self.lineView = [[UIView alloc]init];
                self.lineView.backgroundColor = [UIColor whiteColor];
                self.lineView.height = h;
                self.lineView.width = button.titleLabel.width;
                self.lineView.top = y;
                self.lineView.centerX = button.centerX;
                [self addSubview:self.lineView];
            }   

六、lineView與button的聯(lián)動

  • 設(shè)置block與滑動方法
typedef void(^TopBlock)(NSInteger tag);   


@property ( nonatomic, copy) TopBlock block;

-(void)scrolling:(NSInteger)idx;   
   
  • button的事件
//topView的button點擊事件
-(void)clickTitle:(UIButton *)button{

    self.lineView.centerX = button.centerX;
} 

七、topView與scrollView的聯(lián)動

  • 修改button點擊事件
//topView的button點擊事件
-(void)clickTitle:(UIButton *)button{
    
    self.block(button.tag);

    //點擊按鈕,使ScrollView滑動到相應(yīng)位置(展示相應(yīng)的子視圖控制器)
    [self scrolling:button.tag];
}

//VC滾動時調(diào)用
-(void)scrolling:(NSInteger)idx{
    
    UIButton * button = self.buttons[idx];

    //點擊按鈕,使line滑動到相應(yīng)位置
    [UIView animateWithDuration:0.2 animations:^{
        self.lineView.centerX = button.centerX;
    }];
}   
  • 修改topView的懶加載
@weakify(self);
        _topView.block = ^(NSInteger tag) {
            @strongify(self);
            CGPoint point = CGPointMake(tag * SCREEN_WIDTH, self.contentScrollView.contentOffset.y);
            [self.contentScrollView setContentOffset:point animated:YES];
            
        };   
  • 傳遞聯(lián)動索引值給topView
[self.topView scrolling:idx];   
最終效果圖
finish0.gif

補(bǔ)充

UINavigationController的常用屬性及方法---->傳送門

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

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

  • “北靈之原修行?” 牧塵聽得此話,倒是微微怔了怔,北靈之原是北靈境內(nèi)相當(dāng)聞名的一處險地,其中地域遼闊,更是遍布著各...
    混沌天書閱讀 194評論 0 0
  • 很多時侯,人就是一個演員,天生自帶劇本,但是很多人卻沒有信念感,往往那些不阿諛奉承、不把眼光像個餓狼般向外索取的 ...
    一歲一禮一歡喜閱讀 990評論 0 0
  • 看了同學(xué)們的日記,收獲二字“認(rèn)真”,每個人都在認(rèn)真對待自己的每一天。Legcay 的戰(zhàn)斗力不容低估,我們是一群在不...
    天之心語閱讀 313評論 0 1
  • 先看照片吧,今天回學(xué)校,發(fā)現(xiàn)了近在身邊的牛人: 滴滴打車CTO,貝貝網(wǎng)創(chuàng)始人,虹膜算法領(lǐng)導(dǎo)者,pptv創(chuàng)始人,悅?cè)?..
    京珂大師姐閱讀 268評論 3 4
  • 001.想到就去做,今日復(fù)明日,明日何其多!做了,才能知道會有下一個可能。每個人都有拖延癥,那是因為這件事對你來說...
    June88閱讀 217評論 0 0

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