UITableView 的横向滑动实现
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];
/*
对于UITableViewCell的contentView中的一些默认的视图不会随着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 的横向滑动实现的更多相关文章
- 横向滑动的HorizontalListView滑动指定位置的解决方法
项目中用到了自定义横向滑动的控件:HorizontalListView,点击其中一项,跳转到另外一个大图界面,大图界面也是HorizontalListView,想使用setSelection方法设定 ...
- UICollectionView 图片横向滑动居中偏移量的解决
1.在使用UICollectionView 来显示横向滑动图片的时候,cell与cell之间有间隙,每次滑动后cell都会向左偏移,在使用过这两个方法才解决每次向左偏移的部分. 2.使用方法前不要开启 ...
- 使GridView可以单行横向滑动
最近做的练手的小项目中存在一个横向滑动的问题,需要HorizontalScroll中嵌套GridView,但是GridView默认是竖直排放的item,况且HorizontalScroll与GridV ...
- ios7中使用scrollview来横向滑动图片,自动产生偏移竖向的偏移 问题
ios7中使用scrollview来横向滑动图片,自动产生偏移竖向的偏移 问题 如图红色为scrollview的背景色,在scrollview上加了图片之后,总会有向下的偏移 设置conten ...
- android--解--它们的定义tabhost(动态添加的选项+用自己的主动性横向滑动标签+手势切换标签页和内容特征)
在本文中,解决他们自己的定义tabhost实现,并通过代码集成动态加入标签功能.自己主动标签横向滑动功能.和手势标签按功能之间切换. 我完成了这个完美的解决方案一起以下: 1.定义tabwidget布 ...
- overflow-x: scroll;横向滑动详细讲解
overflow-x: scroll;横向滑动(移动端使用详解) css3 , ie8以上 <!DOCTYPE html> <html lang="en"> ...
- 用css巧妙实现移动端横向滑动展示功能
前言:记得以前处理移动端横向滑动展示都是去用js去解决的,要用js进行蛮多处理,要算li的宽度,然后还要用js设置ul盒子的宽度,又要设置最大滑动距离,最小滑动距离等等.......但是现在发现用cs ...
- iOS8 UICollectionView横向滑动demo
在iOS8中,scrollView和加载在它上面的点击事件会有冲突,所以做一个横向滑动的界面最好的选择就是UICollectionView. 这个效果可以用苹果公司提供的官方demo修改而来,下载地址 ...
- 横向滑动页面,导航条滑动居中的 js 实现思路
最近在做新闻咨询页的项目,各个新闻频道通过横向滑动切换,顶部的导航active栏需要跟着切换到对应频道,并且active到达中部时,要一直处在中间. 类似效果就是uc浏览器<UC头条>的导 ...
随机推荐
- iis 6,7 ftp 进行用户隔离进行权限控制,不同用户查看不同文件夹
iis 6 配置点击链接 http://www.jb51.net/article/20676.htm iis 7配置 1.建立文件夹 C:\ftp, 并增加 目录 localuser(这个是必须的名字 ...
- web测试笔记
WEB兼容性测试 一.客户端兼容性 1.浏览器的兼容性测试 a.内核角度 Tridnt内核:代表作IE.腾讯.遨游.世界之窗等 Gecko内核:代表作Firefox webkit内核:代表作Safar ...
- phprpc的使用示例以及报错Fatal error: Cannot redeclare gzdecode() in D:\wamp\www\immoc\phprpc\compat.php 处理
今天看书,发现了PHPRPC这个好东东,故在此写下来以作笔记. PHPRPC 是一个轻型的.安全的.跨网际的.跨语言的.跨平台的.跨环境的.跨域的.支持复杂对象传输的.支持引用参数传递的.支持内容输出 ...
- June. 21 2018, Week 25th. Thursday
Summertime is always the best of what might be. 万物最美的一面,总在夏季展现. From Charles Bowden. It was June, an ...
- 《Java大学教程》—第18章 高级图形编程
自测题:1. 在图形应用程序中为用户提供选择的多种方式:P433下拉菜单(pull-down menu).弹出式菜单(pop-up menu).对话框窗口(dialogue window).单选 ...
- python的各种推导式
python的各种推导式(列表推导式.字典推导式.集合推导式) 推导式comprehensions(又称解析式),是Python的一种独有特性.推导式是可以从一个数据序列构建另一个新的数据序列的结构体 ...
- Apache Shiro对象概念
#,Authentication,认证,也就是验证用户的身份,就是确定你是不是你,比如通过用户名.密码的方式验证,或者某些第三方认证,比如微信认证. #,Authorization,授权,也叫访问控制 ...
- 机器学习算法总结(四)——GBDT与XGBOOST
Boosting方法实际上是采用加法模型与前向分布算法.在上一篇提到的Adaboost算法也可以用加法模型和前向分布算法来表示.以决策树为基学习器的提升方法称为提升树(Boosting Tree).对 ...
- Redis主从数据库同步
Redis主从同步原理-SYNC和MySQL主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的主从结构可以采 ...
- Python-wxpy信息爬取发送至微信(小白级)
Wxpy初体验 1.1 安装wxpy 在这里默认大家以及安装好了pip,我们需要安装wxpy 以及wechat_sender 两个包,这里推荐使用国内的豆瓣源,如果大家网速过硬 请忽略.. 1 2 p ...