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. c/c++ 标准库 迭代器(iterator)

    c/c++ 标准库 迭代器 begin和end运算符返回的具体类型由对象是否是常量决定,如果对象是常量,begin和end返回const_iterator:如果对象不是常量,返回iteraotor 1 ...

  2. c复杂函数指针

    函数指针,函数的返回值是数组 int *(*(*fun)(int* a, int* b))[]; 上面的代码是声明一个函数指针,这个函数有2个int指针参数,返回值是指针,指向的是数组,数组里放的是i ...

  3. 复制 cmd 窗口文本三步曲:

    1:右键菜单点"标记": 2:按住左键选文字: 3:选完右键点一下!  (关键一步,只需点一下就好!!) so 待选文字就跑到剪切板上了

  4. February 24th, 2018 Week 8th Saturday

    Those are my principles, and if you don't like them... well, I have others. 那是我的原则,要是你不喜欢......那我还有其 ...

  5. Docker: docker 启动一个Nginx容器

    本文演示从官方镜像仓库拉取一个nginx镜像并启动docker run -d –p 8800:80 nginx (同一个镜像,可以启动N个容器, 比如说,一个nginx服务,可以在这个docker主机 ...

  6. FCM算法的matlab程序(初步)

    FCM算法的matlab程序 在https://www.cnblogs.com/kailugaji/p/9648430.html文章中已经介绍了FCM算法,现在用matlab程序实现它. 作者:凯鲁嘎 ...

  7. 使用Razor Generator构建模块化ASP.NET MVC应用程序

    在构建Web应用程序的时候,我们很难做到模块化的开发,这是因为Web应用程序不仅仅包含编译的C#代码,还包含了js.css和aspx等资源. 在ASP.NET MVC中,我们发布应用程序的时候,还会包 ...

  8. Python开发【第三篇】:函数&读写文件

    三元运算 三元运算,是条件语句的简单的写法.如果条件为真,则返回值1,否则,返回值2. ret = 值1 if 条件 else 值2 深浅拷贝 对于数字(int)和字符串(str)而言,赋值.深拷贝. ...

  9. Automatically migrating data to new machines kafka集群扩充迁移topic

    The partition reassignment tool can be used to move some topics off of the current set of brokers to ...

  10. Python:Day20 模块

    模块是用来组织函数的. 模块一共3种: python标准库 第三方模块 应用程序自定义模块 模块搜索路径:sys.path import sys print(sys.path) import calc ...