iOS开发-UIScrollView嵌套tableView实现顶部tab横向切换

iOS开发-UIScrollView嵌套tableView实现顶部tab横向切换

通过ScollView嵌套两个TableView左右切换功能

在这里插入图片描述

在这里插入图片描述

一、UIScollView

UIScrollView可滚动控件,这里初始化需要设置_backScollView.pagingEnabled = YES;

代码如下

_backScollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
_backScollView.backgroundColor = [UIColor colorWithHexString:@"ffffff"];
_backScollView.showsHorizontalScrollIndicator = NO;
_backScollView.showsVerticalScrollIndicator = NO;
_backScollView.userInteractionEnabled = YES;
_backScollView.pagingEnabled = YES;
_backScollView.exclusiveTouch = YES;
_backScollView.scrollEnabled = YES;
_backScollView.tag = kWBackScrollViewTAG;
_backScollView.bounces = NO;
[self addSubview:_backScollView];

完整代码

SDAppWCourseZoneView.h

#import <UIKit/UIKit.h>
#import "UIColor+Addition.h"
#import "SDBaseControllerView.h"
#import "SDAppWCourseNavbarView.h"

#define kWBackScrollViewTAG 1121

@interface SDAppWCourseZoneView : SDBaseControllerView

@property (nonatomic, strong) UIScrollView *backScollView;

@property (nonatomic, strong) SDAppWCourseNavbarView *navbarView;

@property (nonatomic, weak) id delegate;

@end

SDAppWCourseZoneView.m

#import "SDAppWCourseZoneView.h"

static CGFloat kBtnSize = 50.0;
static CGFloat kVPadding = 25.0;
static CGFloat kHPadding = 20.0;

@interface SDAppWCourseZoneView ()<JXCategoryViewDelegate>

@end

@implementation SDAppWCourseZoneView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        
        self.backgroundColor = [UIColor colorWithHexString:@"ffffff"];
        _backScollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
        _backScollView.backgroundColor = [UIColor colorWithHexString:@"ffffff"];
        _backScollView.showsHorizontalScrollIndicator = NO;
        _backScollView.showsVerticalScrollIndicator = NO;
        _backScollView.userInteractionEnabled = YES;
        _backScollView.pagingEnabled = YES;
        _backScollView.exclusiveTouch = YES;
        _backScollView.scrollEnabled = YES;
        _backScollView.tag = kWBackScrollViewTAG;
        _backScollView.bounces = NO;
        [self addSubview:_backScollView];
        
        _navbarView = [[SDAppWCourseNavbarView alloc] initWithFrame:CGRectZero];
        _navbarView.backgroundColor = [UIColor whiteColor];
        [self addSubview:_navbarView];
        // 联动(categoryView和pagingView)
        _navbarView.categoryView.contentScrollView = _backScollView;
        // 返回上一页侧滑手势(仅在index==0时有效)
        
        [self bringSubviewToFront:self.navigationBar];
        self.navigationHiden = YES;
        
        [self layoutAllContentViews];
    }
    return self;
}

- (void)layoutAllContentViews {
    CGFloat navbarHeight = [SDAppWCourseNavbarView navbarHeight];
    self.navbarView.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(self.bounds), navbarHeight);
    self.backScollView.frame = CGRectMake(0.0, CGRectGetMaxY(self.navbarView.frame), CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - CGRectGetMaxY(self.navbarView.frame) - 49.0 - [SDBaseView baseSafeEdgeInsets].bottom);
}

- (void)setDelegate:(id)delegate {
    _delegate = delegate;
    _backScollView.delegate = delegate;
    self.navbarView.categoryView.delegate = self;
}

- (void)dealloc {
    
}

@end

二、分类标题进行切换tab

在切换tab时,使用JXCategoryTitleView

SDAppWCourseNavbarView.h

#import "SDBaseView.h"
#import "JXCategoryView.h"

@interface SDAppWCourseNavbarView : SDBaseView

@property (nonatomic, strong) JXCategoryTitleView *categoryView;

+ (CGFloat)navbarHeight;

@end

SDAppWCourseNavbarView.m

#import "SDAppWCourseNavbarView.h"

static CGFloat kNavbarHeight = 60.0;

static CGFloat kCategoryHeight = 44.0;

@interface SDAppWCourseNavbarView ()

@property (nonatomic, strong) UIImageView *bgImageView;

@end

@implementation SDAppWCourseNavbarView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addSubview:self.bgImageView];
        [self.bgImageView addSubview:self.categoryView];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.bgImageView.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
    self.categoryView.frame = CGRectMake(0.0, kStatusBarHeight + (kNavbarHeight - kCategoryHeight)/2.0, kScreenWidth*3.0/5.0, kCategoryHeight);
}

+ (CGFloat)navbarHeight {
    return kStatusBarHeight + kNavbarHeight;
}

#pragma mark - LAZY
- (UIImageView *)bgImageView {
    if (!_bgImageView) {
        _bgImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _bgImageView.backgroundColor = [UIColor whiteColor];
        _bgImageView.userInteractionEnabled = YES;
    }
    return _bgImageView;
}

/**
 菜单项视图View
 */
-(JXCategoryTitleView *)categoryView{
    if(!_categoryView){
        //
        _categoryView = [[JXCategoryTitleView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth*3.0/5.0, kCategoryHeight)];
        // 设置菜单项标题数组
        _categoryView.titles = [NSMutableArray arrayWithArray:@[@"我的课程", @"挑选课程"]];;
        // 背景色
        _categoryView.backgroundColor = [UIColor whiteColor];
        // 标题色、标题选中色、标题字体、标题选中字体
        _categoryView.titleColor = [UIColor colorWithHexString:@"666666"];
        _categoryView.titleSelectedColor = [UIColor colorWithHexString:@"f78342"];
        _categoryView.titleFont = SDMediumFontSize(15);
        // 标题色是否渐变过渡
        _categoryView.titleColorGradientEnabled = YES;
        _categoryView.titleLabelZoomEnabled = YES;
        _categoryView.titleLabelZoomScale = 1.2;
        _categoryView.titleLabelAnchorPointStyle = JXCategoryTitleLabelAnchorPointStyleBottom;
        
        // 下划线
        JXCategoryIndicatorImageView *lineView = [[JXCategoryIndicatorImageView alloc] init];
        // 下划线颜色
        lineView.indicatorImageView.image = [UIImage imageNamed:@"img_line_bttom"];
        // 下划线宽度
        lineView.indicatorImageViewRollEnabled = NO;
        lineView.indicatorImageViewSize = CGSizeMake(40, 10);
        _categoryView.indicators = @[lineView];
    }
    
    return _categoryView;
}

@end

三、为UIScrollView添加子控件

UIScrollView添加子控件,Controller添加SubController

SDAppWCourseZoneViewController.h

#import "SDBaseViewController.h"

@interface SDAppWCourseZoneViewController : SDBaseViewController

@end

SDAppWCourseZoneViewController.m

#import "SDAppWCourseZoneViewController.h"
#import "SDAppWCourseZoneView.h"
#import "SDAppStudyViewController.h"
#import "SDAppMyCoursePageViewController.h"

@interface SDAppWCourseZoneViewController ()<UIScrollViewDelegate>

@property (nonatomic, strong) SDAppWCourseZoneView *wcourseView;

@property (nonatomic, strong) SDBaseViewController *currentPageController;

@end

@implementation SDAppWCourseZoneViewController

- (instancetype)init {
    self = [super init];
    if (self) {
        self.hidesBottomBarWhenPushed = NO;
    }
    return self;
}

#pragma mark - Configure NavigationBar
- (void)configureNavigationBar {
    SDNavButtonItem *leftButtonItem = [[SDNavButtonItem alloc] initWithTitle:nil image:[UIImage imageNamed:@"ic_nav_back_gray"] target:self action:@selector(leftNavBarButtonAction)];
        
    self.wcourseView.navigationBar.navTitleView = [[SDNavigationTitleView alloc] initWidthTitle:@"消息&通知" subView:nil];
    self.wcourseView.navigationBar.leftNavItem = leftButtonItem;
    self.wcourseView.navigationBar.hidenNavShadow = YES;
}

- (void)leftNavBarButtonAction {
    if (self.routerPresent) {
        [self dismissViewControllerAnimated:YES completion:^{
            // completion
        }];
    } else {
        [self.navigationController popViewControllerAnimated:YES];
    }
}


#pragma mark - loadView
- (void)loadView {
    [super loadView];
    _wcourseView = [[SDAppWCourseZoneView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    _wcourseView.delegate = self;
    self.view = _wcourseView;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self configureNavigationBar];
    
    [self addColumnController];
    self.currentPageController = self.childViewControllers[0];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
}


#pragma mark - 添加子控制器
- (void)addColumnController {
    CGFloat contentWidth = CGRectGetWidth([UIScreen mainScreen].bounds);
    CGFloat contentHeight = CGRectGetHeight([UIScreen mainScreen].bounds) - CGRectGetMaxY(self.wcourseView.navbarView.categoryView.frame) - 49.0 - [SDBaseView baseSafeEdgeInsets].bottom - 20.0;

    SDAppMyCoursePageViewController *pageVC = [[SDAppMyCoursePageViewController alloc] init];
    [self addChildViewController:pageVC];
    pageVC.view.frame = CGRectMake(0*contentWidth, 0.0, contentWidth, contentHeight);
    [self.wcourseView.backScollView addSubview:pageVC.view];

    SDAppStudyViewController *shopPageVC = [[SDAppStudyViewController alloc] init];
    [self addChildViewController:shopPageVC];
    shopPageVC.view.frame = CGRectMake(1*contentWidth, 0.0, contentWidth, contentHeight);
    [self.wcourseView.backScollView addSubview:shopPageVC.view];
    
    self.wcourseView.backScollView.contentSize = CGSizeMake(contentWidth*self.wcourseView.navbarView.categoryView.titles.count, 0.0);
}

#pragma mark - UIScrollViewDelegate
- (void)segmentButtonDidAction:(NSInteger)segmentIndex {
    [self scrollTableViewPage:segmentIndex];
    
    CGRect contentRect = [UIScreen mainScreen].bounds;
    CGFloat contentWidth = CGRectGetWidth(contentRect);
    CGPoint point = CGPointMake(contentWidth*segmentIndex, 0);
    [self.wcourseView.backScollView setContentOffset:point animated:NO];
}

#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.tag == kWBackScrollViewTAG) {
        
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    if (scrollView.tag == kWBackScrollViewTAG) {
        
    }
}

#pragma mark - scrollTableViewPage
- (void)scrollTableViewPage:(NSInteger)page {
    if ([self.currentPageController isKindOfClass:[SDAppMyCoursePageViewController class]]) {
        SDAppMyCoursePageViewController *myCourseVC = (SDAppMyCoursePageViewController *)self.currentPageController;
        [myCourseVC scrollToTop:YES];

    } else if ([self.currentPageController isKindOfClass:[SDAppStudyViewController class]]) {
        SDAppStudyViewController *remCourseVC = (SDAppStudyViewController *)self.currentPageController;
        [remCourseVC scrollToTop:YES];
    }

    self.currentPageController = self.childViewControllers[page];

    if ([self.currentPageController isKindOfClass:[SDAppMyCoursePageViewController class]]) {
        SDAppMyCoursePageViewController *myCourseVC = (SDAppMyCoursePageViewController *)self.currentPageController;
        [myCourseVC scrollToTop:NO];
        
    } else if ([self.currentPageController isKindOfClass:[SDAppStudyViewController class]]) {
        SDAppStudyViewController *remCourseVC = (SDAppStudyViewController *)self.currentPageController;
        [remCourseVC scrollToTop:NO];
    }
    
    [self.currentPageController reloadData];
}

- (void)switchContentPage:(NSInteger)page {
    [self scrollTableViewPage:page];
    
    CGRect contentRect = [UIScreen mainScreen].bounds;
    CGFloat contentWidth = CGRectGetWidth(contentRect);
    CGPoint point = CGPointMake(contentWidth*page, 0);
    [self.wcourseView.backScollView setContentOffset:point animated:NO];
    
    if ([self.currentPageController isKindOfClass:[SDAppStudyViewController class]]) {
        SDAppStudyViewController *shopVC = (SDAppStudyViewController *)self.currentPageController;
        [shopVC reloadData];
    }
}

#pragma mark - JXCategoryViewDelegate
/**
 选中菜单项后调用

 @param categoryView 菜单项View
 @param index 下表
 */
- (void)categoryView:(JXCategoryBaseView *)categoryView didSelectedItemAtIndex:(NSInteger)index {
    [self switchContentPage:index];
}

/**
 滑动并切换内容视图后调用

 @param categoryView 菜单项View
 @param index 下表
 */
- (void)categoryView:(JXCategoryBaseView *)categoryView didScrollSelectedItemAtIndex:(NSInteger)index{
    [self switchContentPage:index];
}


#pragma mark - UIScrollViewDelegate

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

四、小结

iOS开发-UIScrollView嵌套tableView实现顶部tab横向切换.
通过ScollView嵌套两个TableView左右切换功能。

学习记录,每天不停进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/54928.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

98. Python基础教程:try...except...finally语句

【目录】 文章目录 1. try...except...finally语法介绍2. try...except...finally执行顺序3. 捕获特定类型的异常4. 捕获所有类型的异常5. 实操练习-打开txt文件并输出文件内容 【正文】 在今天的课程中&#xff0c;我们将学习Python中的异常处理语句try...except...finally。 …

自定义MVC增删改查

目录 mymvcdemo是自定义mvc框架的使用示例 1.1 实体类 1.2 dao方法 1.3 写Service / biz 三层架构 1.4 建action 相当于selvert 1.5 con连接MySQL 8.0 版本 1.6 配置文件 XML 1.7 主界面布局 1.8 增加界面布局 1.9 写tld配置文件 2.0 注意架包 我是已经打包好的 mymv…

Redis缓存预热

说明&#xff1a;项目中使用到Redis&#xff0c;正常情况&#xff0c;我们会在用户首次查询数据的同时把该数据按照一定命名规则&#xff0c;存储到Redis中&#xff0c;称为冷启动&#xff08;如下图&#xff09;&#xff0c;这种方式在一些情况下可能会给数据库带来较大的压力…

C++ 结构体和联合体

1.结构体 结构体是一种特殊形态的类&#xff0c;它和类一样&#xff0c;可以有自己的数据成员和函数成员&#xff0c;可以有自己的构造函数和析构函数&#xff0c;可以控制访问权限&#xff0c;可以继承&#xff0c;支持包含多态&#xff0c;结构体定义的语法和类的定义语法几…

【ChatGPT】ChatGPT是如何训练得到的?

前言 ChatGPT是一种基于语言模型的聊天机器人&#xff0c;它使用了GPT&#xff08;Generative Pre-trained Transformer&#xff09;的深度学习架构来生成与用户的对话。GPT是一种使用Transformer编码器和解码器的预训练模型&#xff0c;它已被广泛用于生成自然语言文本的各种…

ubuntu远程控制小车 运行rviz时报错

我买的是wheeltec的小车&#xff0c;测试rgbd相机时想在ubuntu上的rviz中显示小车的姿态和看到的rgb和depth图&#xff0c;但是ubuntu中rostopic list和rviz都找不到小车发布的话题信息&#xff0c;运行rqt_image_view时可以显示图片信息。 最终wheeltec的技术人员lucas帮我找了…

MIT 6.S081 Lab Ten -- mmap

MIT 6.S081 Lab Ten -- mmap 引言mmap(hard)代码解析 引言 本文为 MIT 6.S081 2020 操作系统 实验十解析。 MIT 6.S081课程前置基础参考: 基于RISC-V搭建操作系统系列 mmap(hard) map和munmap系统调用允许UNIX程序对其地址空间进行详细控制。它们可用于在进程之间共享内存&a…

基于springboot+mybatis+vue进销存管理信息系统

基于springbootmybatisvue进销存管理信息系统 一、系统介绍二、功能展示1.个人中心2.企业信息管理3.商品信息管理4.客户信息管理5.入库记录管理6.出库记录管理7.出库记录管理8.操作日志管理9.库存盘点管理 四、获取源码 一、系统介绍 系统主要功能&#xff1a; 普通用户&#…

华为OD机试真题 Java 实现【简单的自动曝光】【2023Q1 100分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、备注五、解题思路六、Java算法源码七、效果展示1、输入2、输出3、说明4、再输入5、输出6、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff…

css中flex后文本溢出的问题

原因&#xff1a; 为了给flex item提供一个合理的默认最小尺寸&#xff0c;flex将flex item的min-width 和 min-height属性设置为了auto flex item的默认设置为&#xff1a; min-width&#xff1a; auto 水平flex布局 min-height&#xff1a;auto 垂直flex布局 解决办法&…

PHP8的变量-PHP8知识详解

昨天我们讲解了PHP8的常量&#xff0c;今天讲解PHP8的变量。常量有定义常量和预定义常量&#xff0c;变量呢&#xff1f;那就没有定义变量了&#xff0c;那叫给变量赋值&#xff0c;但是还是有预定义变量的。下面就给大家讲解什么是变量、变量赋值及使用及预定义变量。 一、什么…

zookeeper基础

安装 https://archive.apache.org/dist/zookeeper/zookeeper-3.5.7/ 命令 bin/zkServer.sh start bin/zkServer.sh stop bin/zkServer.sh status bin/zkCli.sh ll / quit 各个配置项的含义&#xff1a; tickTime&#xff1a;每个时钟周期的毫秒数。ZooKeeper使用一个内部…

DevOps系列文章之 java调用python脚本

在java类中直接执行python语句 在java类中直接调用本地python脚本 使用Runtime.getRuntime()执行python脚本文件&#xff08;推荐&#xff09; 调用python脚本中的函数 简单介绍 官网地址 首页 | (jython.org) Jython项目提供了Java中的Python实现&#xff0c; 为Python提供了…

功能测试也可以发现数据库相关的性能问题

很多同学认为功能测试和性能测试是严格分开的&#xff0c;功能测试人员无法发现性能问题。其实不是这样的&#xff0c;功能测试人员在验证功能时也可以发现性能问题&#xff1b;一些功能反而在功能测试环境不好验证&#xff0c;需要在性能环境上测试。 今天咱们就说一下测试涉及…

【Redis】内存数据库Redis进阶(搭建各种集群)

目录 单机安装Redis搭建Redis主从集群搭建Redis哨兵集群 基于 CentOS 7 的 Redis 集群 单机安装Redis 安装 Redis 所需要的依赖&#xff1a; yum install -y gcc tcl将 Redis 安装包&#xff08;redis-6.2.4.tar.gz&#xff09;上传到任意目录 解压缩&#xff1a; tar -xzf …

【数据结构】图文并茂,通过逻辑图带你轻松拿捏链表,实现各种接口功能

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;我们接着之前讲过的顺序表来继续介绍初阶数据结构的内容&#xff0c;今天给大家带来的是有关链表的基本知识和各种接口功能的实现 好了&#xff0c;废话不多说&#x…

【uniapp】实现买定离手小游戏

前言 最近玩了一个小游戏&#xff0c;感觉挺有意思&#xff0c;打算放进我的小程序【自动化小助手】里面&#xff0c;“三张押一张&#xff0c;专押花姑娘&#xff01;”&#xff0c;从三张卡牌&#xff0c;挑选一张&#xff0c;中奖后将奖励进行发放&#xff0c;并且创建下一…

Github-Copilot初体验-Pycharm插件的安装与测试

引言&#xff1a; 80%代码秒生成&#xff01;AI神器Copilot大升级 最近copilot又在众多独角兽公司的合力下&#xff0c;取得了重大升级。GitHub Copilot发布还不到两年&#xff0c; 就已经为100多万的开发者&#xff0c;编写了46%的代码&#xff0c;并提高了55%的编码速度。 …

AMEYA详解松下Panasonic HF SSOP 1 Form A AQY PhotoMOS继电器

Panasonic HF SSOP 1 Form A AQY PhotoMOS继电器采用微型SSOP封装&#xff0c;具有600V的负载电压和1500Vrms 的I/O隔离电压 这些继电器具有8Ω的低导通电阻和高速运行的特点&#xff0c;SSOP封装旨在实现高密度安装。Panasonic HF SSOP AQY PhotoMOS继电器适用于从测试和测量设…

【HDFS】Block、BlockInfo、BlockInfoContiguous、BlockInfoStriped的分析记录

本文主要介绍如下内容: 关于几个Block类之间的继承、实现关系;针对文章标题中的每个类,细化到每个成员去注释分析列出、并详细分析BlockInfo抽象类提供的抽象方法、非抽象方法的功能针对几个跟块组织结构的方法再进行分析。moveBlockToHead、listInsert、listRemove等。一、…
最新文章