iOS常用

UITableview的滑动监听

2021-08-19  本文已影响0人  数字d

需求:

总共有两个View,ViewA和ViewB,当ViewA的frame发生了变化,B的frame也可以发生响应的变化.

这个功能点通过Masonry来实现,这里不做赘述.

下面说下系统提供的解决办法:

1.监听view的frame

[self.view addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];

2.view的frame发生变化时候的回调

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    NSLog(@"滚动了tableview");
    if ([keyPath isEqualToString:@"frame"]) {
        CGPoint offset = [change[NSKeyValueChangeNewKey] CGPointValue];
    }
}

3.移除监听

    [self.view removeObserver:self forKeyPath:@"frame"];

实际在项目中的应用

一个scrollview上叠加一个tableView需求,scrollview的头部是一个View,用户点击一些操作之后,这个view的frame会增加或者减少(这里仅仅指高度),tableView在scrollview上,底部和scrollview对齐.

网上搜了大多数答案都是说要监听scrollview的contentOffset的值,来控制tableview和scrollview的的滑动事件.

网上搜索的几乎所有的实现都不包含tableview的下拉刷新功能.

所以最后找了个demo换了一种思路来实现

效果见

1.gif

1.将scrollview替换成view.给头部的view添加上拉手势,如果上拉就将tableview,contentoffset设置为上拉后的效果

2.tableview的contenteoffset效果监听

具体代码实现vc.m

#import "ViewController.h"

#import "Masonry.h"

#import "PinkViewCtl.h"

#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)

@interface ViewController ()<UIScrollViewDelegate>


@property(nonatomic,strong)UIView * bgScrollView;

@property(nonatomic,strong)UIView * yzclientZBView;

@property(nonatomic,strong)UIView * tabBgView;

@property(nonatomic,strong)PinkViewCtl * vc;

@property(nonatomic,assign)CGFloat greenHeight;
@property(nonatomic,assign)CGFloat redheight;



@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.greenHeight = 220;
    self.redheight = 200;
    
    self.view.backgroundColor = [UIColor whiteColor];
    

    UIView * greenView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, _greenHeight)];
    greenView.backgroundColor = [UIColor greenColor];
    [self.view addSubview:greenView];
    
    [self.view addSubview:self.bgScrollView];
    
    self.vc = [[PinkViewCtl alloc] init];

    [self addChildViewController:self.vc];


    [self.tabBgView addSubview:self.vc.view];

    [self.vc.view mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.top.bottom.equalTo(self.tabBgView);
    }];


    [self.vc.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
//
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    NSLog(@"滚动了tableview");
    if ([keyPath isEqualToString:@"contentOffset"]) {
        CGPoint offset = [change[NSKeyValueChangeNewKey] CGPointValue];
        NSLog(@"滚动的offset.y = %f",offset.y);
        if (offset.y < 0) {
            self.yzclientZBView.frame = CGRectMake(0, 0, SCREEN_WIDTH, _redheight);
            self.yzclientZBView.hidden = NO;
            self.tabBgView.frame = CGRectMake(0, _redheight, self.bgScrollView.frame.size.width, self.bgScrollView.frame.size.height - _redheight);
        }else if(offset.y == 0){
            self.yzclientZBView.frame = CGRectMake(0, 0, SCREEN_WIDTH, _redheight);
            self.yzclientZBView.hidden = NO;
            self.tabBgView.frame = CGRectMake(0, _redheight, self.bgScrollView.frame.size.width, self.bgScrollView.frame.size.height - _redheight);
        }else if (offset.y > 0){
            self.yzclientZBView.hidden = YES;
            self.tabBgView.frame = CGRectMake(0, 0, self.bgScrollView.frame.size.width, self.bgScrollView.frame.size.height);
            self.vc.view.frame = self.tabBgView.frame;
            self.vc.tableView.frame = self.tabBgView.frame;
        }
    }
}




-(UIView *)bgScrollView {
    if (_bgScrollView == nil) {
        _bgScrollView  = [[UIView alloc] initWithFrame:CGRectMake(0, _redheight, SCREEN_WIDTH, SCREEN_HEIGHT - _greenHeight)];
        _bgScrollView.backgroundColor = [UIColor yellowColor];
        [_bgScrollView addSubview:self.yzclientZBView];
        [_bgScrollView addSubview:self.tabBgView];
        
        [_tabBgView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.yzclientZBView.mas_bottom);
            make.left.equalTo(self.yzclientZBView.mas_left);
            make.height.equalTo(@(SCREEN_HEIGHT - _redheight - _redheight));
            make.width.equalTo(@(SCREEN_WIDTH));
        }];
    }
    return _bgScrollView;
}

-(UIView *)yzclientZBView {
    if (_yzclientZBView == nil) {
        _yzclientZBView = [[UIView alloc] init];
        _yzclientZBView.backgroundColor = [UIColor redColor];
         UISwipeGestureRecognizer *recognizer;
          recognizer = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeFrom:)];
          [recognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
          [[self view] addGestureRecognizer:recognizer];
    }
    return _yzclientZBView;
}

-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer{
    
    if(recognizer.direction==UISwipeGestureRecognizerDirectionDown) {
        
        NSLog(@"swipe down");
        //执行程序
    }
    if(recognizer.direction==UISwipeGestureRecognizerDirectionUp) {
        
        NSLog(@"swipe up");
        //执行程序
        self.vc.tableView.contentOffset = CGPointMake(0, 100);
    }
    
    if(recognizer.direction==UISwipeGestureRecognizerDirectionLeft) {
        
        NSLog(@"swipe left");
        //执行程序
    }
    
    if(recognizer.direction==UISwipeGestureRecognizerDirectionRight) {
        
        NSLog(@"swipe right");
        //执行程序
    }
    
}

-(UIView *)tabBgView {
    if (_tabBgView == nil) {
        _tabBgView = [[UIView alloc] init];
        _tabBgView.backgroundColor = [UIColor blueColor];
    }
    return _tabBgView;
}


@end


pinkvc.m

#import "PinkViewCtl.h"
#import "Masonry.h"
#import "MJRefresh.h"



@interface PinkViewCtl ()<UITableViewDelegate,UITableViewDataSource,UIScrollViewDelegate>
@property(nonatomic,strong)NSMutableArray * testArray;
@property(nonatomic,assign)BOOL canMove;

@end

@implementation PinkViewCtl

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor systemPinkColor];
    self.testArray = [NSMutableArray arrayWithArray:@[
        @"need1",
        @"need2",
        @"need3",
        @"need4",
        @"need5",
        @"need6",
        @"need7",
        @"need8",
        @"need1",
        @"need2",
        @"need3",
        @"need4",
        @"need5",
        @"need6",
        @"need7",
        @"need8",
        @"need1",
        @"need2",
        @"need3",
        @"need4",
        @"need5",
        @"need6",
        @"need7",
        @"need8",
        @"need1",
        @"need2",
        @"need3",
        @"need4",
        @"need5",
        @"need6",
        @"need7",
        @"need8",
    ]];
    
    [self.view addSubview:self.tableView];
    
    
    
    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.top.bottom.equalTo(self.view);
    }];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(acceptMsg:) name:@"kHomeGoTopNotification" object:nil];
}

-(UITableView *)tableView {
    if (_tableView == nil) {
        _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:(UITableViewStylePlain)];
        _tableView.dataSource = self;
        _tableView.delegate = self;
        _tableView.rowHeight = 70;
        _tableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
        [_tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
        _tableView.showsVerticalScrollIndicator = NO;

    }
    return _tableView;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.testArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell * cell = [[UITableViewCell alloc] init];
    cell.textLabel.text = @"neeed";
    return  cell;
}




#pragma mark - UIScrollViewDelegate

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}



@end

功能实现中有的瑕疵是:当头部view监听到了上拉手势的时候,对tableview进行上拉,这个过程不够平滑

上一篇 下一篇

猜你喜欢

热点阅读