UITableViewCell嵌套UIScrollView-UI

2021-10-11  本文已影响0人  恩莱客

最近遇到一个需求页面,上下滚动吸顶,支持列表左右滚动,如图:

滚动视图需求

根据需求,我写的页面布局如下:

页面布局框架
简单描述布局逻辑:最底层使用tableView_1 - 主要是想使用其section-head吸顶效果,tableView_1tableViewHeadView是大文字标题,tableView_1tableViewfootViewscrollViewscrollView添加两个tableView_2
完成布局,任务就已完成80%,现在剩下一个最重要问题要解决:嵌套导致的tableView上下滚动冲突问题。相关代码如下:

HDBaseTableView.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN
@interface HDBaseTableView : UITableView<UIGestureRecognizerDelegate>
@end

NS_ASSUME_NONNULL_END

HDBaseTableView.m

@implementation HDBaseTableView
/**
 同时识别多个手势

 @param gestureRecognizer gestureRecognizer description
 @param otherGestureRecognizer otherGestureRecognizer description
 @return return value description
 */
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

@end

HDFormViewController.m

@interface HDFormViewController ()<HDFormListViewDelegate, UITableViewDelegate, UIScrollViewDelegate>
/// 外部tableview
@property (nonatomic, strong) HDBaseTableView *formTableView;
/// 是否滚动
@property (nonatomic, assign) BOOL isCanScroll;

@end

#pragma mark - setter、getter
- (HDBaseTableView *)formTableView{
    if (!_formTableView) {
        _formTableView = [HDBaseTableView new];
        _formTableView.bounces = NO;
        _formTableView.delegate = self;
        _formTableView.showsVerticalScrollIndicator = NO;
        _formTableView.showsHorizontalScrollIndicator = NO;
        _formTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        if (@available(iOS 11.0, *)) {
            _formTableView.estimatedRowHeight = 0;
            _formTableView.estimatedSectionHeaderHeight = 0;
            _formTableView.estimatedSectionFooterHeight = 0;
            _formTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        }
        [_formTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass([UITableViewCell class])];
        _formTableView.tableHeaderView = self.downloadTipView;
        _formTableView.tableFooterView = self.horScrollView;
    }
    return _formTableView;
}

#pragma mark - UIScrollViewDelegate
static CGFloat const headerHeight = 105;
static CGFloat const kCanHideHeaderHeight = 93;
static CGFloat const kHeaderHeight = 105;
static CGFloat const kCanHideHeaderHeight = 93;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    if (scrollView == self.formTableView) {
        self.titleLabel.hidden = !(self.formTableView.contentOffset.y > 45);

        // 外tableview滚动max-offsetY
        if (scrollView.contentOffset.y >= kCanHideHeaderHeight) {
            // 上划吸顶
            scrollView.contentOffset = CGPointMake(0, kCanHideHeaderHeight);
            if (_isCanScroll) {
                // 禁止滚动
                _isCanScroll = NO;
            }
        }else{
            if (!_isCanScroll) {// 外tableView不能滚动时,需要保持吸顶状态
                scrollView.contentOffset = CGPointMake(0, kCanHideHeaderHeight);
            }else{// 外tableView滚动时,内tableView不能滚动
                self.formListView.listTableView.contentOffset = CGPointZero;
            }
        }
    }
}

#pragma mark - NSNotification
- (void)addNotification{
    _isCanScroll = YES;
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(changeScrollStatus) name:kHDChangeScrollStatus object:nil];
}

- (void)changeScrollStatus{
    _isCanScroll = YES;
    // 非0保证下拉刷新
    if (self.formTableView.contentOffset.y != 0) {
        self.formListView.listTableView.contentOffset = CGPointZero;
    }
}

- (void)dealloc{
    [[NSNotificationCenter defaultCenter]removeObserver:self name:kHDChangeScrollStatus object:nil];
}

HDFormListView.m

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    //到顶通知父视图改变状态
    if (scrollView.contentOffset.y <= 0) {
        [[NSNotificationCenter defaultCenter] postNotificationName:kHDChangeScrollStatus object:nil];
    }
}
上一篇下一篇

猜你喜欢

热点阅读