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. Qt的事件

    Qt的事件机制 事件过滤器: 可以让一个对象侦听拦截另外一个对象的事件. 实现原理: 在所有Qt对象的基类:QObject中有一个 类型为:QObjectList 名字为:eventFilters 的 ...

  2. LeetCode算法题-Reverse Vowels of a String(Java实现-四种解法)

    这是悦乐书的第206次更新,第218篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第74题(顺位题号是345).编写一个函数,它将一个字符串作为输入,并仅反转一个字符串的 ...

  3. MATLAB中冒号的用法

    MATLAB中冒号的用法 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ matlab中冒号代表步长,用实例来说明 >> A=[1 2 3 ...

  4. webdriver设置浏览器全屏及设置浏览器窗口为特定大小的方法

    from selenium import webdriver driver = webdriver.Chrome() #全屏 driver.maximize_window() #具体大小 driver ...

  5. MySQL 初识别语句,数据库、表、行的增删改查

    一.MySQL 开场语句 1.登陆 mysql -u root -p ; #回车然后输入密码 2.退出 eixt | quit #二者选其一 3.查看数据文件路径(配置文件中学习的) show glo ...

  6. 【大数据技术】HBase与Solr系统架构设计

    如何在保证存储量的情况下,又能保证数据的检索速度. HBase提供了完善的海量数据存储机制,Solr.SolrCloud提供了一整套的数据检索方案. 使用HBase搭建结构数据存储云,用来存储海量数据 ...

  7. ab和jmeter进行GET/POST压力测试的使用心得和比较

    引言: 互联网服务压测是非常重要的评价方法,ab,webbench,jmeter等都是业界流行的测试工具,ab和webbench作为shell模式下轻量级的测试工具,jmeter则作为有GUI界面的更 ...

  8. WinForm下的loading框的实现

    前言:在项目使用C/S模式情况下,由于需要经常进行数据的刷新,如果直接进行刷新,会有一个等待控件重画的过程,非常的不友好,因此在这里添加一个loading框进行等待显示. 实现:在经过多方面查询资料, ...

  9. 转://Oracle 11gR2 硬件导致重新添加节点

    一.环境描述:        这是一套五年前部署的双节点单柜11g RAC,当时操作系统盘是一块164g的单盘,没有做RAID.        OS: RedHat EnterPrise 5.5 x8 ...

  10. 【转】CefSharp语言(Locales)本地化问题

    CefSharp默认是嵌入的chrome浏览器内核,默认英文,所以右键菜单以及一些功能都是英文显示. 国内用需要汉化.CefSharp本身支持本地化Locales,需要在初始化Browser的时候设置 ...