UIScrollView 六棱柱图片浏览
头疼脑胀的代码搬运工 人气:0一、效果展示
废话开篇:利用 CATransform3D 图形变换及 UIScrollView 的一些方法实现一个六棱柱图片浏览效果
二、实现原理
1、在一个基础 View 上添加六棱柱的六个侧面视图。
2、调整六棱柱的各个侧面的旋转角度及z轴数值。
3、基础 View 放在 UIScrollView 上,通过监听 UIScrollView 的滑动来设置基础 View 的坐标x值与与y轴的旋转角度。
三、代码
创建 PhotoDrumBrowseView 图片浏览类视图
#import "PhotoDrumBrowseView.h" @interface PhotoDrumBrowseView()<UIScrollViewDelegate> @property(nonatomic,strong) UIScrollView * baseScrollView; @property(nonatomic,strong) UIView * baseView; @property(nonatomic,assign) CGRect originalBaseViewFrame; @end @implementation PhotoDrumBrowseView - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { [self createUI]; [self addDrumBrowseImageView]; } return self; } - (void)createUI{ //滚动视图其实主要是用来通过位置偏移进行计算旋转的角度(通过偏移量与总宽度计算旋转角度与一周2π的比值) self.baseScrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; self.baseScrollView.showsHorizontalScrollIndicator = NO; [self addSubview:self.baseScrollView]; CGFloat cellWidth = self.frame.size.width * 5.0 / 6.0; CGFloat cellHeight = cellWidth / 0.618; //加载六棱柱六个面 self.baseView = [[UIView alloc] initWithFrame:CGRectMake((self.frame.size.width - cellWidth) / 2.0, (self.frame.size.height - cellHeight) * 1 / 3.0, cellWidth, cellHeight)]; self.originalBaseViewFrame = self.baseView.frame; [self.baseScrollView addSubview:self.baseView]; } //创建六棱柱面 - (void)addDrumBrowseImageView{ int num = 6; //一些角度计算 float radian = (M_PI * 2) / num; float cellWidth = self.baseView.frame.size.width / 2.0; float cellHeight = cellWidth / 0.618; //前后z轴偏移值 float needBFOff = cellWidth * sin(radian); //左右x轴偏移值 float needLROff = cellWidth / 2.0 * cos(radian) + cellWidth / 2.0; self.baseScrollView.contentSize = CGSizeMake(self.frame.size.width / 2.0 + self.baseView.frame.size.width * num, 0); self.baseScrollView.delegate = self; for (int i = 0; i < num; i ++) { UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake((self.baseView.frame.size.width - cellWidth) / 2.0, (self.baseView.frame.size.height - cellHeight) / 2.0, cellWidth, cellHeight)]; imageView.contentMode = UIViewContentModeScaleAspectFill; imageView.clipsToBounds = YES; imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"fd%d",i % 3 + 1]]; [self.baseView addSubview:imageView]; switch (i) { case 0: { //前左 imageView.layer.transform = CATransform3DTranslate(imageView.layer.transform, -needLROff, 0,needBFOff / 2.0); imageView.layer.transform = CATransform3DRotate(imageView.layer.transform,- radian, 0, 1, 0); } break; case 1: { //前 imageView.layer.transform = CATransform3DTranslate(imageView.layer.transform, 0, 0, needBFOff); } break; case 2: { //前右 imageView.layer.transform = CATransform3DTranslate(imageView.layer.transform, needLROff, 0,needBFOff / 2.0); imageView.layer.transform = CATransform3DRotate(imageView.layer.transform, radian, 0, 1, 0); } break; case 3: { //前右 imageView.layer.transform = CATransform3DTranslate(imageView.layer.transform, needLROff, 0, - needBFOff / 2.0); imageView.layer.transform = CATransform3DRotate(imageView.layer.transform,- radian, 0, 1, 0); } break; case 4: { //后 imageView.layer.transform = CATransform3DTranslate(imageView.layer.transform, 0, 0, - needBFOff); } break; case 5: { //后左 imageView.layer.transform = CATransform3DTranslate(imageView.layer.transform, -needLROff, 0,- needBFOff / 2.0); imageView.layer.transform = CATransform3DRotate(imageView.layer.transform, radian, 0, 1, 0); } break; default: break; } } //同时设置六个面的透视参数 CATransform3D transformPerspective = CATransform3DIdentity; transformPerspective.m34 = -1.0f/800; self.baseView.layer.sublayerTransform = transformPerspective; } #pragma mark - 滚动进行图形变换 - (void)scrollViewDidScroll:(UIScrollView *)scrollView { float offset = CGRectGetMinX(self.originalBaseViewFrame); //通过偏移量计算应该绕y轴旋转的角度 float persent = (scrollView.contentOffset.x - offset) / (scrollView.contentSize.width - offset); //修改基础视图的frame,保持相对位置不变 self.baseView.frame = CGRectMake(self.originalBaseViewFrame.origin.x + scrollView.contentOffset.x, self.originalBaseViewFrame.origin.y, self.originalBaseViewFrame.size.width, self.originalBaseViewFrame.size.height); //进行y轴旋转 CATransform3D transformR = CATransform3DMakeRotation(-(M_PI * 2) * persent, 0, 1, 0); CATransform3D transformPerspective = CATransform3DIdentity; transformPerspective.m34 = -1.0f/800; self.baseView.layer.sublayerTransform = CATransform3DConcat(transformR, transformPerspective); } @end
四、总结与思考
简单的六棱柱图片浏览就完成了,复杂的部分主要是计算六个面的位置及y轴旋转角度,可以通过修改六个面的视图,丰富一下内部的功能。view 在经过 transform 设置之后,它的 frame 的属性值也会随着修改,如果从扩展一些功能也是可以的。比如,有个菱形的按钮,那么,是不是可以将按钮沿x轴、y轴都进行选择得到一个菱形,这样的菱形按钮的点击范围就会在其内部了。
加载全部内容