UITableView 的横向滑动实现

概述

为了实现横向滑动的控件,可以继承类 UIScrollView 或类 UIView 自定义可以横向滑动的控件,这里通过 UITableView 的旋转,实现可以横向滑动的控件。

概念

先说明与实现相关的几个概念

坐标系

iOS 中,每个视图都有一个坐标系,用来确定其子视图的位置,这个坐标系在视图初始化后

确定,在这个长方形的视图中,左上角为坐标系原点,水平向右为 x 坐标轴正方向,垂直向下

y 坐标轴正方向,当视图发生旋转时,其坐标系同时旋转(或者说旋转的就是坐标系),但

这并不会影响父视图的坐标系,但旋转视图的 frame 属性会发生改变,如果旋转后的视图的坐

标系仍然与父坐标系平行,那么,frame 表示的仍然是这个视图,如果不平行,那么,frame 

表示的是该旋转视图的外接正方形。

 

frame

对于这个 UIView 的属性 frame ,包含四个值(x,y,width,height),(x,y)这个

点坐标代表的是视图在其父视图坐标系中的某一点,而 width 则是沿着 x 坐标轴的长度,

height 则是沿着 y 坐标轴的长度,由此得来的矩形即是 frame 表示的视图,这里的坐

标轴指的都是父坐标系。

 

transform

这个属性实际是提供了一个3*3的矩阵,当修改这个属性时,视图上的点会组成一个1*3的矩

[x,y,1],这个矩阵与 transform 表示的矩阵相乘,计算出新的点。在实际使用过程中

可以直接使用 CGAffineTransform.h 中提供的函数得到一个 CGAffineTransform 

变量,然后赋值即可。

本次就会用到函数 

    CGAffineTransformMakeRotation(CGFloat angle) 

        参数:angle ,弧度值,可以直接使用系统定义的宏 M_PI

        该值为正值时,表示坐标系逆时针方向旋转,为负值时,表示坐标系顺时针方向

        旋转(这是在 iOS 中的旋转方向,在 Mac X 中相反,并且这里指的是坐标轴

        的自我旋转方向,而人眼看到的方向是相反的,即正值,你看到的视图是在顺时

        针旋转)

 

锚点

视图旋转总是相对于某一点旋转,这个点就是锚点,该点默认是视图的中心点,也可以通过

UIView layer anchorPoint 属性改变,

 

原理

自定义一个 UIView 的子类 HorizontalTableView ,在其中添加一个 UITableView 类对象,初始化时,将表格视图逆时针方向旋转90度,此时,其坐标系的 x 坐标轴正方向垂直向上, y 坐标轴正方向水平向右,表格中的子视图的坐标系与其一致,而后,在该自定义的子类中实现 UITableView 的代理方法。

自定义一个类 HorizontalTableViewCell 继承 UITableViewCell ,在初始化该子类时,将属性 contentView 顺时针方向旋转90度,此时其坐标系方向与 HorizontalTableView 的父视图的坐标系一致(一般与屏幕一致)。

自定义一个协议 HorizontalTableViewDataSource 用于获取用户提供的 cell 个数及宽度等信息。

代码

完整测试代码

HorizontalTableView.h

//

//  HorizontalTableView.h

//  Test-horizontalTableView

//

//  Created by han on 2017/3/22.

//  Copyright © 2017 han. All rights reserved.

//

#import <UIKit/UIKit.h>

@class HorizontalTableViewCell;

@protocol HorizontalTableViewDataSource;

@interface HorizontalTableView : UIView

@property (nonatomic, weak) id <HorizontalTableViewDataSource> delegate;

/** 

 the default width of columns,value is 50.0

 if the delegate don't implement the method tableView:widthForColumnAtIndex:

 the value is used as the width of columns,you can change the default value.

 */

@property (nonatomic, assign) CGFloat width;

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier;

- (void)selectColumnAtIndex:(NSInteger)index animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;

- (void)reloadData;

- (HorizontalTableViewCell *)cellForColumn:(NSInteger)column;

@end

@protocol HorizontalTableViewDataSource <NSObject>

@required

- (NSInteger)numberOfColumnsInTableView:(HorizontalTableView *)tableView;

- (HorizontalTableViewCell *)tableView:(HorizontalTableView *)tableView cellForColumnAtIndex:(NSInteger)index;

@optional

- (CGFloat)tableView:(HorizontalTableView *)tableView widthForColumnAtIndex:(NSInteger)index;

- (void)tableView:(HorizontalTableView *)tableView didSelectColumn:(NSInteger)index;

@end

@interface HorizontalTableViewCell : UITableViewCell

@end

 

HorizontalTableView.m

//

//  HorizontalTableView.m

//  Test-horizontalTableView

//

//  Created by han on 2017/3/22.

//  Copyright © 2017 han. All rights reserved.

//

#import "HorizontalTableView.h"

@interface HorizontalTableView ()<UITableViewDelegate,UITableViewDataSource>

@property (nonatomic, strong) UITableView *tableView;

@end

@implementation HorizontalTableView

#pragma mark - initial methods

- (instancetype)init {

    self = [super init];

    if (self) {

        self = [self initWithFrame:CGRectMake(0, 0, 320, 50)];

    }

    return self;

}

- (instancetype)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];

    if (self) {

        self.tableView.transform = CGAffineTransformMakeRotation(- M_PI_2);

        self.tableView.delegate = self;

        self.tableView.dataSource = self;

        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

        self.tableView.frame = self.bounds;

        self.tableView.backgroundColor = [UIColor clearColor];

        [self addSubview:self.tableView];

        self.width = 50;

    }

    return self;

}

- (void)setFrame:(CGRect)frame {

    [super setFrame:frame];

    self.tableView.frame = self.bounds;

}

#pragma mark - accessor methods

- (UITableView *)tableView {

    if (_tableView == nil) {

        _tableView = [[UITableView alloc]init];

    }

    return _tableView;

}

#pragma mark - inside methods

#pragma mark - interface methods

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier {

    id cell = [self.tableView dequeueReusableCellWithIdentifier:identifier];

    return cell;

}

- (void)selectColumnAtIndex:(NSInteger)index animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition {

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];

    [self.tableView selectRowAtIndexPath:indexPath animated:animated scrollPosition:scrollPosition];

}

- (void)reloadData {

    [self.tableView reloadData];

}

- (HorizontalTableViewCell *)cellForColumn:(NSInteger)index {

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];

    HorizontalTableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    return cell;

}

#pragma mark - UITableViewDelegate,UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    NSInteger columns = 0;

    if (self.delegate != nil && [self.delegate respondsToSelector:@selector(numberOfColumnsInTableView:)]) {

        columns = [self.delegate numberOfColumnsInTableView:self];

    }

    return columns;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    HorizontalTableViewCell *cell = nil;

    if (self.delegate != nil && [self.delegate respondsToSelector:@selector(tableView:cellForColumnAtIndex:)]) {

        cell = [self.delegate tableView:self cellForColumnAtIndex:indexPath.row];

    }

    return cell;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    CGFloat cellHeight = self.width;

    if (self.delegate != nil && [self.delegate respondsToSelector:@selector(tableView:widthForColumnAtIndex:)]) {

        cellHeight = [self.delegate tableView:self widthForColumnAtIndex:indexPath.row];

    }

    return cellHeight;

}

@end

@implementation HorizontalTableViewCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

{

    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {

        self.contentView.transform = CGAffineTransformMakeRotation(M_PI_2);

        self.contentView.backgroundColor = [UIColor clearColor];

        self.backgroundColor = [UIColor clearColor];

    }

    return self;

}

- (void)layoutSubviews {

    [super layoutSubviews];

    /*

     对于UITableViewCellcontentView中的一些默认的视图不会随着frame的改变而自动改变,

     所以需要进行位置的调整,这里只对textLabel的位置进行了调整,其他若使用,也许调整,

     但是不建议使用。

     */

    for (UIView *subView in [self.contentView subviews]) {

        if ([subView class] == NSClassFromString(@"UITableViewLabel")) {

            subView.frame = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.width);

            subView.backgroundColor = [UIColor clearColor];

        }

    }

}

@end

--------------------- 

作者:那夜的星空分外清澈 

来源:CSDN 

原文:https://blog.csdn.net/u011374318/article/details/66260623 

版权声明:本文为博主原创文章,转载请附上博文链接!

2015年12月21日 15:36:48 fyanyan 阅读数:5160

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fyanyan/article/details/50372376

#import "ViewController.h"

#define FYColor(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]

#define FYRandomColor FYColor(arc4random_uniform(255),arc4random_uniform(255),arc4random_uniform(255))

@interface ViewController ()<UITableViewDataSource,UITableViewDelegate>

@property(strong,nonatomic) UITableView *MyTableView;

@end

@implementation ViewController

- (void)viewDidLoad

{

[super viewDidLoad];

self.MyTableView = [[UITableView alloc]initWithFrame:CGRectMake(60, 0, 300,self.view.frame.size.width) style:UITableViewStylePlain];

self.MyTableView.dataSource=self;

self.MyTableView.delegate=self;

//TableView要做的设置

self.MyTableView.transform=CGAffineTransformMakeRotation(-M_PI / 2);

self.MyTableView.showsVerticalScrollIndicator=NO;

[self.view addSubview:self.MyTableView];

}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

{

return 1;

}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

return 100;

}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FyCell"];

if (!cell) {

cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"FyCell"];

}

//Cell要做的设置

cell.backgroundColor=FYRandomColor;

cell.textLabel.transform = CGAffineTransformMakeRotation(M_PI/2);

cell.textLabel.text= @"tableview竖向滚动";

return cell;

}

UITableView 的横向滑动实现的更多相关文章

  1. 横向滑动的HorizontalListView滑动指定位置的解决方法

    项目中用到了自定义横向滑动的控件:HorizontalListView,点击其中一项,跳转到另外一个大图界面,大图界面也是HorizontalListView,想使用setSelection方法设定 ...

  2. UICollectionView 图片横向滑动居中偏移量的解决

    1.在使用UICollectionView 来显示横向滑动图片的时候,cell与cell之间有间隙,每次滑动后cell都会向左偏移,在使用过这两个方法才解决每次向左偏移的部分. 2.使用方法前不要开启 ...

  3. 使GridView可以单行横向滑动

    最近做的练手的小项目中存在一个横向滑动的问题,需要HorizontalScroll中嵌套GridView,但是GridView默认是竖直排放的item,况且HorizontalScroll与GridV ...

  4. ios7中使用scrollview来横向滑动图片,自动产生偏移竖向的偏移 问题

    ios7中使用scrollview来横向滑动图片,自动产生偏移竖向的偏移 问题     如图红色为scrollview的背景色,在scrollview上加了图片之后,总会有向下的偏移 设置conten ...

  5. android--解--它们的定义tabhost(动态添加的选项+用自己的主动性横向滑动标签+手势切换标签页和内容特征)

    在本文中,解决他们自己的定义tabhost实现,并通过代码集成动态加入标签功能.自己主动标签横向滑动功能.和手势标签按功能之间切换. 我完成了这个完美的解决方案一起以下: 1.定义tabwidget布 ...

  6. overflow-x: scroll;横向滑动详细讲解

    overflow-x: scroll;横向滑动(移动端使用详解) css3 , ie8以上 <!DOCTYPE html> <html lang="en"> ...

  7. 用css巧妙实现移动端横向滑动展示功能

    前言:记得以前处理移动端横向滑动展示都是去用js去解决的,要用js进行蛮多处理,要算li的宽度,然后还要用js设置ul盒子的宽度,又要设置最大滑动距离,最小滑动距离等等.......但是现在发现用cs ...

  8. iOS8 UICollectionView横向滑动demo

    在iOS8中,scrollView和加载在它上面的点击事件会有冲突,所以做一个横向滑动的界面最好的选择就是UICollectionView. 这个效果可以用苹果公司提供的官方demo修改而来,下载地址 ...

  9. 横向滑动页面,导航条滑动居中的 js 实现思路

    最近在做新闻咨询页的项目,各个新闻频道通过横向滑动切换,顶部的导航active栏需要跟着切换到对应频道,并且active到达中部时,要一直处在中间. 类似效果就是uc浏览器<UC头条>的导 ...

随机推荐

  1. iis 6,7 ftp 进行用户隔离进行权限控制,不同用户查看不同文件夹

    iis 6 配置点击链接 http://www.jb51.net/article/20676.htm iis 7配置 1.建立文件夹 C:\ftp, 并增加 目录 localuser(这个是必须的名字 ...

  2. web测试笔记

    WEB兼容性测试 一.客户端兼容性 1.浏览器的兼容性测试 a.内核角度 Tridnt内核:代表作IE.腾讯.遨游.世界之窗等 Gecko内核:代表作Firefox webkit内核:代表作Safar ...

  3. phprpc的使用示例以及报错Fatal error: Cannot redeclare gzdecode() in D:\wamp\www\immoc\phprpc\compat.php 处理

    今天看书,发现了PHPRPC这个好东东,故在此写下来以作笔记. PHPRPC 是一个轻型的.安全的.跨网际的.跨语言的.跨平台的.跨环境的.跨域的.支持复杂对象传输的.支持引用参数传递的.支持内容输出 ...

  4. June. 21 2018, Week 25th. Thursday

    Summertime is always the best of what might be. 万物最美的一面,总在夏季展现. From Charles Bowden. It was June, an ...

  5. 《Java大学教程》—第18章 高级图形编程

    自测题:1.    在图形应用程序中为用户提供选择的多种方式:P433下拉菜单(pull-down menu).弹出式菜单(pop-up menu).对话框窗口(dialogue window).单选 ...

  6. python的各种推导式

    python的各种推导式(列表推导式.字典推导式.集合推导式) 推导式comprehensions(又称解析式),是Python的一种独有特性.推导式是可以从一个数据序列构建另一个新的数据序列的结构体 ...

  7. Apache Shiro对象概念

    #,Authentication,认证,也就是验证用户的身份,就是确定你是不是你,比如通过用户名.密码的方式验证,或者某些第三方认证,比如微信认证. #,Authorization,授权,也叫访问控制 ...

  8. 机器学习算法总结(四)——GBDT与XGBOOST

    Boosting方法实际上是采用加法模型与前向分布算法.在上一篇提到的Adaboost算法也可以用加法模型和前向分布算法来表示.以决策树为基学习器的提升方法称为提升树(Boosting Tree).对 ...

  9. Redis主从数据库同步

    Redis主从同步原理-SYNC和MySQL主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的主从结构可以采 ...

  10. Python-wxpy信息爬取发送至微信(小白级)

    Wxpy初体验 1.1 安装wxpy 在这里默认大家以及安装好了pip,我们需要安装wxpy 以及wechat_sender 两个包,这里推荐使用国内的豆瓣源,如果大家网速过硬 请忽略.. 1 2 p ...