美文网首页
Segment浅析(附scrollView与tableView手

Segment浅析(附scrollView与tableView手

作者: 沙漠骑士 | 来源:发表于2017-09-08 16:35 被阅读150次

    涉及到Segment的时候就不自觉地找个第三方解决一下,前期还觉得沾沾自喜,任务解决了,当更深入的了解一下就懵逼了,啥都不会,最近觉得Segment用的比较频繁,而第三方写的很是复杂,所以就自己写了两个简单的:
    1.具有手势切换能力(scrollView代理方法里面将滑动手势和标题按钮点击关联)
    2.没有手势切换能力
    下面是代码时间
    快创建创建一个控制器以及四个子控制器试试吧


    创建控制器
    #import <UIKit/UIKit.h>
    
    @interface GestureCommoneViewController : UIViewController
    
    @end
    
    
    //
    //  GestureCommoneViewController.m
    //  SGSegmentedControlExample
    //
    //  Created by APEW on 2017/9/8.
    //  Copyright © 2017年 Jason. All rights reserved.
    //
    
    #import "GestureCommoneViewController.h"
    //下面的四个控制器只做了背景色处理
    #import "TestOneVC.h"
    #import "TestTwoVC.h"
    #import "TestThreeVC.h"
    #import "TestFourVC.h"
    //UIView的category 涉及frame必备,没有加类似于mas_这样的前缀,最讨厌这种工具类加前缀的,好像不知道他写的似的
    #import "UIView+Extension.h"
    //下面都是些快捷写法,一般在PCH文件中
    #define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
    #define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
    #define VHeight SCREEN_HEIGHT - 64
    #define NavH 64
    #define TabH 49
    
    NSString  *const TitleButtonDidRepeatClickNotification = @"TitleButtonDidRepeatClickNotification";
    @interface GestureCommoneViewController ()<UIScrollViewDelegate>//若是不要手势可不加
    @property (nonatomic ,strong)UIScrollView *mainScrlooView;
    @property (nonatomic,  weak) UIView *titlesView;
    /**标题下滑线*/
    @property(nonatomic,strong) UIView * titleUnderline;
    /**滑动按钮*/
    @property(nonatomic,strong) UIButton * titleBtn;
    @end
    
    @implementation GestureCommoneViewController
    //将scrollView的scrollEnable和处理标题view里面button的点击关联,假如不需要滑动,则把scrollView的代理去掉
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
        self.edgesForExtendedLayout = UIRectEdgeNone;//navigation下面为坐标原点(0,0)
        [self setupAllChildControllers];
        // 添加第0个子控制器的view
        [self addChildVcViewIntoScrollView:0];
    }
    -(void)dealloc{
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    - (void)setupAllChildControllers{
        TestOneVC *vc1 = [TestOneVC new];
        TestTwoVC *vc2 = [TestTwoVC new];
        TestThreeVC *vc3 = [TestThreeVC new];
        TestFourVC *vc4 = [TestFourVC new];
        [self addChildViewController:vc1];
        [self addChildViewController:vc2];
        [self addChildViewController:vc3];
        [self addChildViewController:vc4];
        [self setupMainScrollerView];
        [self setupTitleView];
    }
    - (void)setupMainScrollerView{
        UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, VHeight)];
        scrollView.showsHorizontalScrollIndicator = NO;
        scrollView.showsVerticalScrollIndicator = NO;
        scrollView.backgroundColor = [UIColor whiteColor];
    //    scrollView.scrollEnabled = NO;//默认为Yes//若是不要手势设置为NO
        scrollView.bounces = NO;
        scrollView.pagingEnabled = YES;
        scrollView.scrollsToTop = NO; // 点击状态栏的时候,这个scrollView不会滚动到最顶部
        scrollView.delegate = self;//若是不要手势可不加
        [self.view addSubview:scrollView];
        self.mainScrlooView = scrollView;
        NSUInteger count = self.childViewControllers.count;
        //    CGFloat scrollViewW = scrollView.width;
        scrollView.contentSize = CGSizeMake(count * SCREEN_WIDTH, 0);
        
    }
    
    - (void)setupTitleView{
        UIView *titlesView = [[UIView alloc] init];
        titlesView.backgroundColor = [UIColor whiteColor];
        
        titlesView.frame = CGRectMake(0, 0, SCREEN_WIDTH, 44);
        
        [self.view addSubview:titlesView];
        self.titlesView = titlesView;
        // 标题栏按钮
        [self setupTitleButtons];    
        // 标题下划线
        [self setupTitleUnderline];
    }
    - (void)setupTitleButtons{
        NSArray* titles = @[@"天气",@"科技",@"生活",@"娱乐"];//随便啥写了四个button标题
        NSUInteger count = titles.count;
        //标题按钮的尺寸
        CGFloat titleButtonW = self.titlesView.width/count;
        CGFloat titleButtonH = self.titlesView.height;
        for (NSUInteger i = 0; i<count; i++) {
            UIButton * titleButton = [[UIButton alloc]init];
            [titleButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
            titleButton.tag = i;
            [titleButton addTarget:self action:@selector(titleButtonClick:) forControlEvents:UIControlEventTouchUpInside];
            [self.titlesView addSubview:titleButton];
            titleButton.frame = CGRectMake(i*titleButtonW, 0, titleButtonW, titleButtonH);
            [titleButton setTitle:titles[i] forState:UIControlStateNormal];
        }
        
    }
    - (void)setupTitleUnderline{
        UIButton * firstTitleButton = self.titlesView.subviews.firstObject;
        //下划线
        UIView * titleUnderline = [[UIView alloc]init];
        titleUnderline.height = 2;
        titleUnderline.y = self.titlesView.height - titleUnderline.height;
        titleUnderline.backgroundColor = [UIColor redColor];
        [self.titlesView addSubview:titleUnderline];
        self.titleUnderline = titleUnderline;
        firstTitleButton.selected = YES;
        self.titleBtn = firstTitleButton;
        [firstTitleButton.titleLabel sizeToFit];
        self.titleUnderline.width = firstTitleButton.width;
        self.titleUnderline.centerX = firstTitleButton.centerX;
    }
    - (void)titleButtonClick:(UIButton *)titleButton{
        
        if (self.titleBtn == titleButton) {
            [[NSNotificationCenter defaultCenter]postNotificationName:TitleButtonDidRepeatClickNotification object:nil];
        }
        // 处理标题按钮点击
        [self dealTitleButtonClick:titleButton];
    }
    - (void)dealTitleButtonClick:(UIButton*)titleButton{
        
        self.titleBtn.selected = NO;
        titleButton.selected = YES;
        self.titleBtn = titleButton;
        NSUInteger index = titleButton.tag;
        [UIView animateWithDuration:0.25 animations:^{
            //处理下划线
            self.titleUnderline.width = titleButton.width;
            self.titleUnderline.centerX = titleButton.centerX;
            CGFloat offsetX = self.mainScrlooView.width*index;
            self.mainScrlooView.contentOffset = CGPointMake(offsetX, self.mainScrlooView.contentOffset.y);
        }completion:^(BOOL finished) {
            [self addChildVcViewIntoScrollView:index];
        }];    
        for (NSUInteger i = 0; i<self.childViewControllers.count; i++) {  
            UIViewController * childVc = self.childViewControllers[i];
            if (!childVc.isViewLoaded)continue;
            UIScrollView *scrollView = (UIScrollView*)childVc.view;
            if (![scrollView isKindOfClass:[UIScrollView class]]) continue;
            scrollView.scrollsToTop = (i == index);
        }   
    }
    - (void)addChildVcViewIntoScrollView:(NSInteger)index{ 
        UIViewController*childVc = self.childViewControllers[index];
        if (childVc.isViewLoaded) return;
        // 设置子控制器view的frame
        // 取出index位置对应的子控制器view
        UIView *childVcView = childVc.view;
        CGFloat scrollViewW = self.mainScrlooView.width;
        childVcView.frame = CGRectMake(index * scrollViewW, 44, scrollViewW, self.mainScrlooView.height);
        // 添加子控制器的view到scrollView中
        [self.mainScrlooView addSubview:childVcView];    
    }
    //如果不添加手势,既没有scrollView的代理及方法了
    #pragma -mark scrolleViewDelegate
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        // 求出标题按钮的索引
        NSUInteger index = scrollView.contentOffset.x / scrollView.width;
        // 点击对应的标题按钮
        self.titleBtn = self.titlesView.subviews[index];
        //    [self titleButtonClick:titleButton];
        [self dealTitleButtonClick:self.titleBtn];    
    }
    @end
    

    千外别走开哦,涉及到手势问题就会涉及到手势冲突处理。
    说一个我遇到的情况,子控制器的里面是一个最常见的tableView,cell的删除原生的里面有个侧滑(向左滑),这时候就要做手势冲突处理,还是代码啦
    创建一个


    scrollView子类继承UIScrollView
    #import <UIKit/UIKit.h>
    @interface FSScrollViewGes : UIScrollView<UIGestureRecognizerDelegate>
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
    @end
    
    #import "FSScrollViewGes.h"
    @implementation FSScrollViewGes
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
        return [otherGestureRecognizer.view.superview isKindOfClass:[UITableView class]];
    }
    @end
    

    其实就是判断一下手势来自何方,使用方法也是很简单就是利用刚刚写好的子类去创建scrollView就好了

    //用FSScrollViewGes去创建ScrollView,既下面第一句话替代原有的创建方法就好
    UIScrollView *scrollView = [[FSScrollViewGes alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, VHeight)];
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, VHeight)];
    

    这样的话tableView的侧滑删除方能正常侧滑出来,否则多侧滑几次也是可以出来,但是那真的需要运气

    - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
        return YES;
    }
    - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return UITableViewCellEditingStyleDelete;
    }
    - (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
    添加一个删除action(UITableViewRowAction)
    }
    

    OK,结束,我的方法就是简单的实现一下功能,完成基本的功能,想要各种花式
    1.比如最前面的全局属性button,你可以自定义,那样就是各种花式的button
    2.假如需要titleView能滚动,那么就把titleView由UIView换成UIScrollView
    沙漠骑士

    相关文章

      网友评论

          本文标题:Segment浅析(附scrollView与tableView手

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