UIScrollView實現(xiàn)六棱柱圖片瀏覽效果
一、效果展示
廢話開篇:利用 CATransform3D 圖形變換及 UIScrollView 的一些方法實現(xiàn)一個六棱柱圖片瀏覽效果

二、實現(xiàn)原理
1、在一個基礎 View 上添加六棱柱的六個側(cè)面視圖。

2、調(diào)整六棱柱的各個側(cè)面的旋轉(zhuǎn)角度及z軸數(shù)值。

3、基礎 View 放在 UIScrollView 上,通過監(jiān)聽 UIScrollView 的滑動來設置基礎 View 的坐標x值與與y軸的旋轉(zhuǎn)角度。
三、代碼
創(chuàng)建 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{
//滾動視圖其實主要是用來通過位置偏移進行計算旋轉(zhuǎn)的角度(通過偏移量與總寬度計算旋轉(zhuǎn)角度與一周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];
}
//創(chuàng)建六棱柱面
- (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;
}
}
//同時設置六個面的透視參數(shù)
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軸旋轉(zhuǎn)的角度
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軸旋轉(zhuǎn)
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四、總結(jié)與思考
簡單的六棱柱圖片瀏覽就完成了,復雜的部分主要是計算六個面的位置及y軸旋轉(zhuǎn)角度,可以通過修改六個面的視圖,豐富一下內(nèi)部的功能。view 在經(jīng)過 transform 設置之后,它的 frame 的屬性值也會隨著修改,如果從擴展一些功能也是可以的。比如,有個菱形的按鈕,那么,是不是可以將按鈕沿x軸、y軸都進行選擇得到一個菱形,這樣的菱形按鈕的點擊范圍就會在其內(nèi)部了。
以上就是UIScrollView實現(xiàn)六棱柱圖片瀏覽效果的詳細內(nèi)容,更多關于UIScrollView 六棱柱圖片瀏覽的資料請關注腳本之家其它相關文章!
相關文章
IOS計步器功能實現(xiàn)之Healthkit和CMPedometer
現(xiàn)在越來越多的人關注運動和健康,iOS系統(tǒng)也在很早的時候就自帶了健康APP,下面詳細描述一下在我們開發(fā)中,怎么實現(xiàn)計步器功能。2016-08-08
IOS用AFN發(fā)送字符串形式的Json數(shù)據(jù)給服務器實例
本篇文章主要介紹了IOS用AFN發(fā)送字符串形式的Json數(shù)據(jù)給服務器實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-04-04
詳解ios監(jiān)聽reloadData刷新列表完畢的時機
這篇文章主要介紹了詳解ios監(jiān)聽reloadData刷新列表完畢的時機,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-11-11
詳解IOS UITableViewCell 的 imageView大小更改
這篇文章主要介紹了詳解IOS UITableViewCell 的 imageView大小更改的相關資料,需要的朋友可以參考下2017-07-07

