ナンセンスの始まり:CATransform3Dグラフィック変換とUIScrollViewのいくつかのメソッドを使用して、六角形の画像ブラウジング効果を実現します
1.エフェクト表示
第二に、実現原理
1.ベースビューに六角柱の6つの側面図を追加します。
2.六角柱の各辺の回転角とz軸の値を調整します。
3.ベースビューはUIScrollViewに配置され、ベースビューの座標x値とy軸との回転角は、 UIScrollViewのスライドを監視することによって設定されます。
3.コード
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
4.まとめと考え方
簡単な六角形の画像ブラウジングが完了します。複雑な部分は、主に6つの面の位置とy軸の回転角を計算することです。6つの面のビューを変更することで、内部機能を充実させることができます。変換によってビューが設定された後、そのフレームのプロパティ値も変更され、そこからいくつかの関数を拡張することもできます。たとえば、ひし形のボタンがある場合、 x軸とy軸に沿ってボタンを選択してひし形のボタンを取得できるため、このようなひし形のボタンのクリック範囲は次のようになります。その中で。コードは不器用です、偉大な神を笑わないでください