废话开篇:使用 CATransform3D 图形转换及 UIScrollView 的一些方法完结一个六棱柱图片阅览作用

一、作用展现

使用 UIScrollView 完成六棱柱图片阅览作用

二、完结原理

1、在一个基础 View 上增加六棱柱的六个侧面视图。

使用 UIScrollView 完成六棱柱图片阅览作用

2、调整六棱柱的各个侧面的旋转角度及z轴数值。

使用 UIScrollView 完成六棱柱图片阅览作用

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轴都进行选择得到一个菱形,这样的菱形按钮的点击范围就会在其内部了。代码低劣,大神勿笑[抱拳][抱拳][抱拳]