기술나눔

iOS UITableView에는 슬라이딩 제스처가 포함되어 있으며 상위 뷰에는 슬라이딩 제스처 충돌 응답 메커니즘 탐색이 추가되었습니다.

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

장면

때때로 우리는 다음과 같은 대화형 시나리오를 접하게 됩니다. UITableView가 있습니다.
팝업 창에 배치합니다. 이 팝업 창은 슬라이딩(손으로 스와이프)하여 표시하고 사라질 수 있습니다. 그러면 이 UITableView가 팝업 창에 배치되고 스크롤하여 다음과 같은 일부 콘텐츠를 표시할 수 있습니다. 제품 정보 및 댓글(Douyin의 댓글 팝업창과 유사), 아래로 슬라이드할 때 tableView가 위로 슬라이드된 경우 슬라이딩 동작에 반응하여 팝업창을 계속 아래로 슬라이드할 수 있습니다.

아이디어

먼저 팝업 보기에 tableView가 있습니다. 이 tableView는 정상적으로 슬라이드할 수 있습니다. 그런 다음 팝업 보기에 슬라이딩 동작을 추가하여 팝업 프레임을 수정합니다. 창문.따라서 이 팝업 보기는 제스처에 응답하는 프록시입니다.
광장과

  • (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer는 GestureRecognizer와 동시에 인식해야 합니다:(UIGestureRecognizer *)otherGestureRecognizer
    프록시 메소드에서 GestureRecognizer가 자체 슬라이딩 제스처이고 otherGestureRecognizer가 tableView의 슬라이딩 제스처인 경우 동시 응답, 즉 YES를 반환해야 하는 동시에 아이디어가 있어야 합니다. 우리의
    tableView가 상단으로 스크롤되면 tablView의 스크롤 동작이 응답을 지원하지 않도록 설정해야 합니다. 그렇지 않으면 tableView가 상단으로 스크롤될 때 계속 스크롤됩니다. 팝업 및 tableView 발생 동시 스크롤의 경우 이는 우리가 원하지 않는 것이므로 tablView가 맨 위로 스크롤될 때 tableView의 pangesture.enabled = NO를 설정해야 합니다.

듀얼 스와이프 제스처 스크롤 응답 메커니즘

팝업 창에 슬라이딩 동작을 추가하고 응답 방법은 handlerPan입니다.
테스트를 통해 우리는 다음을 발견했습니다.tableView에서 손으로 스크롤할 때마다 실행할 때마다
tableView의 프록시 메소드인 scrollViewDidScroll 이전에 handlerPan 메소드가 실행됩니다.

이미지 설명을 추가해주세요

또한 스와이프 중에(손이 화면을 떠나지 않으면 동일한 스와이프로 계산됩니다.)
응답 메소드인 handlerPan에 설정된 경우
self.tableView.panGestureRecognizer.enabled = NO;
self.tableView는 이 슬라이드 중에 스크롤되지 않습니다. self.tableView.panGestureRecognizer.enabled = YES가 self.tableView.panGestureRecognizer.enabled = NO 이후에 설정되어 있어도 스크롤되지 않습니다.

이는 **슬라이딩 제스처에 대한 응답으로 self.tableView.panGestureRecognizer.enabled = NO가 가장 높은 우선순위를 가짐을 보여줍니다.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    NSLog(@"哈哈哈哈哈这里是执行scrollViewDidScroll self.panNum是%ld", self.panNum);
}

  • 1
  • 2
  • 3
  • 4
  • 5
- (void)handlePan:(UIPanGestureRecognizer *)pan
{
   self.tableView.panGestureRecognizer.enabled = YES;

   NSLog(@"哈哈哈哈哈这是第%ld次响应滑动手势handlePan 方法", self.panNum);
   if (self.panNum % 2 == 0) {
       self.tableView.panGestureRecognizer.enabled = NO;
   } else {
       self.tableView.panGestureRecognizer.enabled = YES;
   }
   self.tableView.panGestureRecognizer.enabled = YES;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

이미지 설명을 추가해주세요

위 테스트의 전체 코드

//
//  LBPangestureController.m
//  TEXT
//
//  Created by mac on 2024/7/7.
//  Copyright © 2024 刘博. All rights reserved.
//

#import "LBPangestureController.h"

@interface LBPangestureController () <UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate>

@property (nonatomic, strong) UITableView *tableView;

@property (nonatomic, strong) UIPanGestureRecognizer *pangesture;

@property (nonatomic, assign) NSInteger panNum;

@end

@implementation LBPangestureController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.tableView];
    [self.view addGestureRecognizer:self.pangesture];
    // Do any additional setup after loading the view.
}


- (void)handlePan:(UIPanGestureRecognizer *)pan
{
    self.tableView.panGestureRecognizer.enabled = YES;

    NSLog(@"哈哈哈哈哈这是第%ld次响应滑动手势handlePan 方法", self.panNum);
    if (self.panNum % 2 == 0) {
        self.tableView.panGestureRecognizer.enabled = NO;
    } else {
        self.tableView.panGestureRecognizer.enabled = YES;
    }
    self.tableView.panGestureRecognizer.enabled = YES;
}

#pragma mark  - UITableViewDelegate, UITableViewDataSource

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([UITableViewCell class])];
    cell.textLabel.text = [NSString stringWithFormat:@"%ld", indexPath.row];
    return cell;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 100;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 60;
}

#pragma mark - uiscrollViewdelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    NSLog(@"哈哈哈哈哈这里是执行scrollViewDidScroll self.panNum是%ld", self.panNum);
}

#pragma mark - gesturedelegate

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer == self.pangesture) {
        self.panNum ++;
    }
    return YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if (gestureRecognizer == self.pangesture && otherGestureRecognizer == self.tableView.panGestureRecognizer) {
        return YES;
    }
    return NO;
}

#pragma mark - lazy load

- (UITableView *)tableView
{
    if (!_tableView) {
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 100, 300, 400) style:UITableViewStylePlain];
        [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass([UITableViewCell class])];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.backgroundColor = [UIColor cyanColor];
    }
    return _tableView;
}

- (UIPanGestureRecognizer *)pangesture
{
    if (!_pangesture) {
        _pangesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
        _pangesture.delegate = self;
    }
    return _pangesture;
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122