iOS 仿热门话题界面(tableView)

作者: Devil雅馨 | 来源:发表于2016-09-27 11:41 被阅读3190次

    好久没来简书分享代码了, 最近在写一个项目, 项目中有一个地方想分享, 废话不多说直接上代码!

    这个功能应该是挺常见的, 一个tableView到另一个tableView, 类似segment的一个东西, 我把它封装起来了:

    //
    //  ViewController.m
    //
    //
    //  Created by 高雅馨 on 16/6/3.
    //  Copyright © 2016年 高雅馨. All rights reserved.
    //
    
    #import "DCNavTabBarController.h"
    #import "HTMacro.h"
    
    @interface DCNavTabBarController ()<UIScrollViewDelegate>
    @property (nonatomic, weak) UIButton *oldBtn;
    @property(nonatomic,strong) NSArray *VCArr;
    @property (nonatomic, weak) UIScrollView *contentView;
    @property (nonatomic, weak) UIScrollView *topBar;
    @property(nonatomic,assign) CGFloat btnW ;
    @property (nonatomic, weak) UIView *slider;
    
    @end
    
    @implementation DCNavTabBarController
    -(UIColor *)sliderColor
    {
        if(_sliderColor == nil)
        {
            _sliderColor = [UIColor colorWithRed:1.00 green:0.36 blue:0.25 alpha:1.00];
        }
        return  _sliderColor;
    }
    -(UIColor *)btnTextNomalColor
    {
        if(_btnTextNomalColor == nil)
        {
            _btnTextNomalColor = [UIColor colorWithWhite:0.205 alpha:1.000];
        }
        return _btnTextNomalColor;
    }
    -(UIColor *)btnTextSeletedColor
    {
        if(_btnTextSeletedColor == nil)
        {
            _btnTextSeletedColor = [UIColor colorWithRed:1.00 green:0.36 blue:0.25 alpha:1.00];
        }
        return _btnTextSeletedColor;
    }
    -(UIColor *)topBarColor
    {
        if(_topBarColor == nil)
        {
            _topBarColor = [UIColor whiteColor];
        }
        return _topBarColor;
    }
    -(instancetype)initWithSubViewControllers:(NSArray *)subViewControllers
    {
        if(self = [super init])
        {
            _VCArr = subViewControllers;
        }
        return self;
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        //添加上面的导航条
        [self addTopBar];
        //添加子控制器
        [self addVCView];
        //添加滑块
        [self addSliderView];
    }
    -(void)addSliderView
    {
        if(self.VCArr.count == 0) return;
        UIView *slider = [[UIView alloc]initWithFrame:CGRectMake(25,41,self.btnW - 50, 3)];
        slider.backgroundColor = self.sliderColor;
        [self.topBar addSubview:slider];
        self.slider = slider;
    }
    -(void)addTopBar
    {
        if(self.VCArr.count == 0) return;
        NSUInteger count = self.VCArr.count;
        UIScrollView *scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 44)];
        scrollView.backgroundColor = self.topBarColor;
        self.topBar = scrollView;
        self.topBar.bounces = NO;
        [self.view addSubview:self.topBar];
        if(count <= 5) {
             self.btnW = SCREEN_WIDTH / count;
        } else {
             self.btnW = SCREEN_WIDTH / 5.0;
        }
        //添加button
        for (int i = 0; i<count; i++) {
            UIViewController *vc = self.VCArr[i];
            UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(i*self.btnW, 0, self.btnW, 44)];
            btn.titleLabel.font = [UIFont systemFontOfSize:15];
            btn.titleLabel.numberOfLines = 0;
            btn.titleLabel.textAlignment = 1;
            btn.tag = 10000+i;
            [btn setTitleColor:self.btnTextNomalColor forState:UIControlStateNormal];
            [btn setTitleColor:self.btnTextSeletedColor forState:UIControlStateSelected];
            [btn setTitle:vc.title forState:UIControlStateNormal];
            [btn addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
            [self.topBar addSubview:btn];
            if(i == 0)
            {
                btn.selected = YES;
                self.oldBtn = btn;
            }
    }
        self.topBar.contentSize = CGSizeMake(self.btnW *count, -64);
    }
    -(void)addVCView
    {
        UIScrollView *contentView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0+44, SCREEN_WIDTH, SCREEN_HEIGHT -44)];
        self.contentView = contentView;
        self.contentView.bounces = NO;
        contentView.delegate = self;
        contentView.backgroundColor = [UIColor colorWithWhite:0.859 alpha:1.000];
        [self.view addSubview:contentView];
        
        NSUInteger count = self.VCArr.count;
        for (int i=0; i<count; i++) {
            UIViewController *vc = self.VCArr[i];
            [self addChildViewController:vc];
            vc.view.frame = CGRectMake(i*SCREEN_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT -44);
            [contentView addSubview:vc.view];
        }
        contentView.contentSize = CGSizeMake(count*SCREEN_WIDTH, SCREEN_HEIGHT - 44);
        contentView.pagingEnabled = YES;
    }
    -(void)click:(UIButton *)sender
    {
        if(sender.selected) return;
        self.oldBtn.selected = NO;
        sender.selected = YES;
        self.contentView.contentOffset = CGPointMake((sender.tag - 10000) *SCREEN_WIDTH, 0);
         self.oldBtn.transform = CGAffineTransformIdentity;
        self.oldBtn = sender;
        
        //判断导航条是否需要移动
        CGFloat maxX = CGRectGetMaxX(self.slider.frame);
        if(maxX >=SCREEN_WIDTH  && sender.tag != self.VCArr.count + 10000 - 1)
        {
            [UIView animateWithDuration:0.3 animations:^{
                self.topBar.contentOffset = CGPointMake(maxX - SCREEN_WIDTH + self.btnW, -64);
            }];
        }else if(maxX < SCREEN_WIDTH)
        {
            [UIView animateWithDuration:0.3 animations:^{
                self.topBar.contentOffset = CGPointMake(0, 0);
            }];
        }
    }
    -(void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        //滑动导航条
        self.slider.frame = CGRectMake(scrollView.contentOffset.x / SCREEN_WIDTH *self.btnW +  25 , 41, self.btnW - 50, 3);
    }
    //判断是否切换导航条按钮的状态
    -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        CGFloat offX =  scrollView.contentOffset.x;
        int tag = (int)(offX /SCREEN_WIDTH + 0.5) + 10000;
        UIButton *btn = [self.view viewWithTag:tag];
        if(tag != self.oldBtn.tag)
        {
            [self click:btn];
        }
    }
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    @end
    

    这个很容易看懂的, 是不是, 就不在这里多解释.


    上面这张呢, 则是把导航栏隐藏, 自定义一个小UIView截取网络图片作为导航栏, 又自定义一个大View作为tableView头视图.并且我还运用了观察者注册消息通知, 代码有点长, 不过我写注释了哦, 可以看懂的.

    //
    //  BookMarksViewController.m
    //  HotTopic
    //
    //  Created by dllo on 16/9/7.
    //  Copyright © 2016年 高雅馨. All rights reserved.
    //
    
    #import "BookMarksViewController.h"
    #import "HTMacro.h"
    #import "UIView+Extension.h"
    #import "BookTableViewCell.h"
    #import "EssayViewController.h"
    #import "SubscriberViewController.h"
    #import "UMSocial.h"
    #import "DCNavTabBarController.h"
    #import "UIImageView+WebCache.h"
    #import "AFNetworking.h"
    #import "HotTopicsModel.h"
    #import "TopicModel.h"
    #import "NodeModel.h"
    #import "UserModel.h"
    #import "Source.h"
    #import "DisposeViewController.h"
    #import "HeadImageView.h"
    static CGFloat const headViewHeight = 280;
    @interface BookMarksViewController ()<UITableViewDelegate,UITableViewDataSource>
    @property (nonatomic, strong) BookTableViewCell * mainTableView;
    @property (nonatomic, strong) HeadImageView * headImageView;//头部图片
    @property (nonatomic, strong) UIImageView * avatarImage;
    @property (nonatomic, strong) UILabel * countentLabel;
    @property (nonatomic, strong) UIImageView *img;
    @property (nonatomic, strong) HotTopicsModel *hotTopic;
    @property (nonatomic, strong) UILabel *titleLabel;
    @property (nonatomic, assign) BOOL canScroll;
    @property (nonatomic, assign) BOOL isTopIsCanNotMoveTabView;
    @property (nonatomic, assign) BOOL isTopIsCanNotMoveTabViewPre;
    @property (nonatomic, strong)  UIView *barView;
    @property (nonatomic, strong) UILabel *titleText;
    
    @end
    
    @implementation BookMarksViewController
    @synthesize mainTableView;
    
    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        [self.navigationController setNavigationBarHidden:YES];
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
    // 这个api功能就是在NavigationController堆栈内的UIViewController可以支持右滑手势,也就是不用点击右上角的返回按钮,轻轻在屏幕左边一
    滑,屏幕就会返回,随着ios设备屏幕的增大,这个小功能让手指短,拇指大和手残人士看到了福音。
        self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
        [self.navigationController setNavigationBarHidden:YES];
        self.automaticallyAdjustsScrollViewInsets = NO;
        [self.view addSubview:self.mainTableView];
        // 设置tableView头视图
        self.mainTableView.tableHeaderView = self.headImageView;
        // 将导航栏隐藏使其变为透明
        [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
        // 将导航栏那条黑线隐藏
        [self.navigationController.navigationBar setShadowImage:[UIImage new]];
        /** 观察者注册消息通知 */
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(leaveTop:) name:@"leaveTop" object:nil];
        [self creatView];
    }
    // 把导航栏写成自定义View
    - (void)creatView {
        _barView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 64)];
        UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
        backButton.frame = CGRectMake(10, 30, 30, 30);
        [backButton setImage:[UIImage imageNamed:@"backBar"] forState:UIControlStateNormal];
        [backButton addTarget:self action:@selector(clickBackBtn:) forControlEvents:UIControlEventTouchUpInside];
        UIButton *shareBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        shareBtn.frame = CGRectMake(SCREEN_WIDTH - 50, 30, 30, 30);
        [shareBtn setImage:[UIImage imageNamed:@"shareBar"] forState:UIControlStateNormal];
        [shareBtn addTarget:self action:@selector(clickShareBtn:) forControlEvents:UIControlEventTouchUpInside];
        _titleText = [[UILabel alloc] initWithFrame:CGRectMake(50, 30, SCREEN_WIDTH - 100, 30)];
        _titleText.text = @"收藏夹";
        _titleText.textAlignment = 1;
        _titleText.textColor = [UIColor whiteColor];
        // 毛玻璃效果
        UIBlurEffect *blur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
        UIVisualEffectView *effectview = [[UIVisualEffectView alloc] initWithEffect:blur];
        effectview.backgroundColor = [UIColor colorWithWhite:0.508 alpha:1.000];
        effectview.alpha = 0.65;
        effectview.frame = CGRectMake(0, 0, SCREEN_WIDTH, 64);
        [_barView addSubview:effectview];
        [_barView addSubview:backButton];
        [_barView addSubview:shareBtn];
        [_barView addSubview:_titleText];
        [self.view addSubview:_barView];
    }
    /**
     * notificationObserver 观察者 : self
     * notificationSelector 处理消息的方法名: getUserProfileSuccess
     * notificationName 消息通知的名字: Notification_GetUserProfileSuccess
     * notificationSender 消息发送者 : 表示接收哪个发送者的通知,如果第四个参数为nil,接收所有发送者的通知
     */
    - (void)leaveTop:(NSNotification *)notification{
        NSDictionary *userInfo = notification.userInfo;
        NSString *canScroll = userInfo[@"canScroll"];
        if ([canScroll isEqualToString:@"1"]) {
            _canScroll = YES;
        }
    }
    /** 将自定义View的背景图设置tableView头视图的背景图*/
    - (UIImage *)clipImageInOffsetY:(CGFloat)y
    {
        if (_headImageView.image == nil) {
            return [UIImage new];
        }
        CGRect rect = CGRectMake(0, y, SCREEN_WIDTH, 64);
        CGImageRef imageRef = CGImageCreateWithImageInRect([_headImageView.image CGImage], rect);
        self.blurView.frame = CGRectMake(0, 0, SCREEN_WIDTH, 64);
        self.blurView.alpha = 0.7;
        [self.navigationController.navigationBar addSubview:_blurView];
        UIImage *thumbScale = [UIImage imageWithCGImage:imageRef];
        return thumbScale;
    }
    // 用scrollView的偏移量来判断
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
        CGFloat yOffset  = scrollView.contentOffset.y;
        if (yOffset >= _headImageView.height - 64)  {
            yOffset = _headImageView.height - 64;
        }
        UIImage *image = [self clipImageInOffsetY:yOffset];
        _barView.backgroundColor = [UIColor colorWithPatternImage:image];
        //获取滚动视图y值的偏移量
        self.navigationController.navigationBar.alpha = (headViewHeight+yOffset)/(headViewHeight-64);
        CGFloat tabOffsetY = [mainTableView rectForSection:0].origin.y - 64.0f;
        CGFloat offsetY = scrollView.contentOffset.y;
        _isTopIsCanNotMoveTabViewPre = _isTopIsCanNotMoveTabView;
        if (offsetY >= tabOffsetY) {
            //不能滑动
            scrollView.contentOffset = CGPointMake(0, tabOffsetY);
            _isTopIsCanNotMoveTabView = YES;
            _titleText.text = self.urlTitle;
        }else{
            //可以滑动
            _isTopIsCanNotMoveTabView = NO;
            _titleText.text = @"收藏夹";
        }
        if (_isTopIsCanNotMoveTabView != _isTopIsCanNotMoveTabViewPre) {
            if (!_isTopIsCanNotMoveTabViewPre && _isTopIsCanNotMoveTabView) {
                [[NSNotificationCenter defaultCenter] postNotificationName:@"goTop" object:nil userInfo:@{@"canScroll":@"1"}];
                _canScroll = NO;
            }
            if(_isTopIsCanNotMoveTabViewPre && !_isTopIsCanNotMoveTabView){
                if (!_canScroll) {
                    scrollView.contentOffset = CGPointMake(0, tabOffsetY);
                }
            }
        }
        
    }
    // 头视图
    - (UIImageView *)headImageView
    {
        if (_headImageView == nil)
        {
            _headImageView = [[HeadImageView alloc]initWithFrame:CGRectMake(0, 0,SCREEN_WIDTH,headViewHeight)];
            _headImageView.userInteractionEnabled = YES;
            [_headImageView sd_setImageWithURL:[NSURL URLWithString:self.urlHeadImg] placeholderImage:[UIImage imageNamed:@"touxiang"]completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                
            }];
            UIBlurEffect *blur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
            UIVisualEffectView *effectview = [[UIVisualEffectView alloc] initWithEffect:blur];
            effectview.backgroundColor = [UIColor colorWithWhite:0.508 alpha:1.000];
            effectview.alpha = 0.7;
            effectview.frame = CGRectMake(0, 0, SCREEN_WIDTH, headViewHeight);
            [_headImageView addSubview:effectview];
            self.navigationController.hidesBarsOnSwipe = NO;
            _avatarImage = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20 + 64, SCREEN_WIDTH / 3.3, SCREEN_WIDTH / 3.3)];
            [_headImageView addSubview:_avatarImage];
            _avatarImage.userInteractionEnabled = YES;
            _avatarImage.layer.masksToBounds = YES;
            [ _avatarImage sd_setImageWithURL:[NSURL URLWithString:self.urlHeadImg] placeholderImage:[UIImage imageNamed:@"detailViewDefaultMidImage"]];
            _countentLabel = [[UILabel alloc] initWithFrame:CGRectMake(_avatarImage.frame.size.width + 40, 20 + 64, SCREEN_WIDTH - (SCREEN_WIDTH / 3 + 20 + 10), _avatarImage.frame.size.height / 4)];
            _countentLabel.font = [UIFont systemFontOfSize:15];
            _countentLabel.textColor = [UIColor whiteColor];
            _countentLabel.lineBreakMode = NSLineBreakByWordWrapping;
            _countentLabel.numberOfLines = 0;
            _countentLabel.text = self.urlTitle;
            [_headImageView addSubview:_countentLabel];
            
            _img = [[UIImageView alloc] initWithFrame:CGRectMake(_countentLabel.frame.origin.x, _countentLabel.frame.size.height + _avatarImage.frame.origin.y +  10, 30, 30)];
            _img.layer.cornerRadius = 15;
            _img.layer.masksToBounds = YES;
            _img.backgroundColor = [UIColor yellowColor];
            [_headImageView addSubview:_img];
            _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(_img.frame.size.width + _img.frame.origin.x + 5, _img.frame.origin.y, SCREEN_WIDTH / 1.9 , 30)];
            _titleLabel.textColor = [UIColor whiteColor];
            _titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
            _titleLabel.numberOfLines = 0;
            _titleLabel.font = [UIFont systemFontOfSize:12];
            [_headImageView addSubview:_titleLabel];
            UILabel *contextLabel = [[UILabel alloc] initWithFrame:CGRectMake(_img.frame.origin.x , _img.frame.origin.y + _img.frame.size.height + 6, SCREEN_WIDTH / 2 , SCREEN_WIDTH / 8)];
            contextLabel.textColor = [UIColor whiteColor];
            contextLabel.text = self.urlContect;
            contextLabel.lineBreakMode = NSLineBreakByWordWrapping;
            contextLabel.numberOfLines = 0;
            contextLabel.font = [UIFont systemFontOfSize:12];
            [_headImageView addSubview:contextLabel];
            UIButton *takeBtn = [UIButton buttonWithType:UIButtonTypeSystem];
            takeBtn.frame = CGRectMake(_img.frame.origin.x - 20 , contextLabel.frame.size.height + contextLabel.frame.origin.y + 10, SCREEN_WIDTH / 4, _avatarImage.frame.size.height / 3.2);
            [takeBtn setTitle:@"+ 订阅" forState:UIControlStateNormal];
            [takeBtn setTitleColor:[UIColor whiteColor]  forState:UIControlStateNormal];
            takeBtn.backgroundColor = [UIColor colorWithRed:1.00 green:0.36 blue:0.25 alpha:1.00];
            takeBtn.titleLabel.font = [UIFont systemFontOfSize:14];
            takeBtn.layer.cornerRadius = 10;
            [_headImageView addSubview:takeBtn];
            UIButton *contributeBtn = [UIButton buttonWithType:UIButtonTypeSystem];
            contributeBtn.frame = CGRectMake(takeBtn.frame.origin.x + takeBtn.frame.size.width + 5, contextLabel.frame.size.height + contextLabel.frame.origin.y + 10, SCREEN_WIDTH / 8, _avatarImage.frame.size.height / 3.2);
            [contributeBtn setTitle:@"投稿" forState:UIControlStateNormal];
            [contributeBtn setTitleColor:[UIColor whiteColor]  forState:UIControlStateNormal];
            contributeBtn.layer.borderWidth = 1.0;
            contributeBtn.titleLabel.font = [UIFont systemFontOfSize:14];
            contributeBtn.layer.borderColor = [UIColor whiteColor].CGColor;
            contributeBtn.layer.cornerRadius = 5;
            [_headImageView addSubview:contributeBtn];
            UIButton *manageLabel = [[UIButton alloc] initWithFrame:CGRectMake(contributeBtn.frame.size.width + contributeBtn.frame.origin.x, contributeBtn.frame.origin.y + 5, SCREEN_WIDTH / 5 , 30)];
            [manageLabel setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
            [manageLabel setTitle:@"0未处理☞" forState:UIControlStateNormal];
            manageLabel.titleLabel.textAlignment = 0;
            manageLabel.titleLabel.font = [UIFont systemFontOfSize:12];
            [manageLabel addTarget:self action:@selector(clickManageBtn:) forControlEvents:UIControlEventTouchUpInside];
            [_headImageView addSubview:manageLabel];
            
        }
        return _headImageView;
    }
    // 大tableView
    -(UITableView *)mainTableView
    {
        if (mainTableView == nil)
        {
            mainTableView= [[BookTableViewCell alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH,SCREEN_HEIGHT)];
            mainTableView.delegate = self;
            mainTableView.dataSource=self;
            mainTableView.bounces = NO;
            mainTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
            mainTableView.showsVerticalScrollIndicator = NO;
            mainTableView.backgroundColor = [UIColor clearColor];
            mainTableView.rowHeight = SCREEN_HEIGHT;
        }
        return mainTableView;
    }
    
    #pragma marl -tableDelegate
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
        return 1;
    }
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return 1;
    }
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        return SCREEN_HEIGHT;
    }
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        //添加pageView
        [cell.contentView addSubview:self.setPageViewControllers];
        return cell;
    }
    // 调用两个小VC
    -(UIView *)setPageViewControllers{
        EssayViewController *essay = [[EssayViewController alloc] init];
        essay.urlStr = self.urlStr;
        essay.title = [NSString stringWithFormat:@"文章\n%@", self.articleCount];
        SubscriberViewController *subscribe = [[SubscriberViewController alloc] init];
        subscribe.urlStr = self.urlStr;
        subscribe.title = [NSString stringWithFormat:@"订阅者\n%@", self.subscriberCount];
        NSArray *subViewControllers=@[essay, subscribe];
        DCNavTabBarController *tabBarVC = [[DCNavTabBarController alloc]initWithSubViewControllers:subViewControllers];
        tabBarVC.view.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
        [self.view addSubview:tabBarVC.view];
        [self addChildViewController:tabBarVC];
        return tabBarVC.view;
    }
    @end
    

    写到这里, 就完成了, 下面让我们来看一下成果吧!


    是不是特别棒呢, 喜欢的话就来试试看吧!🤗有什么不足和建议可以评论哦, 我会虚心接受的, 喜欢给个赞👍哦!

    相关文章

      网友评论

      本文标题:iOS 仿热门话题界面(tableView)

      本文链接:https://www.haomeiwen.com/subject/dsjcyttx.html