本文控件主要用在产品的浏览的时候,针对现在一些变态的需求,做了一个无限循环滚动的控件。产品图片的展示浏览,也可以是可以来用的,这个效果比较有个逐渐显示和隐藏的功能在里面,所以在用户滑动的时候,有一种高大上的感觉!
效果如下,看起来有点卡的原因是因为制作的这个gif不行,实际上是很流畅的
先直接上代码,然后说明在穿插给上!
使用方法
先导入头文件 #import "PShowView.h"
然后 创建PShowView控件,并添加到相应的视图之上(本文这里是控制器,所以添加到了self.view上了)
这里的PShowItemModel是因为要把数据赋值给每个产品的展示上,所以建立了一个模型,读者可以自己在这个模型中修改成员变量,然后在PShowItem的 -setModel: 方法中进行调整赋值
NSMutableArray * arr = [NSMutableArray array];
PShowItemModel * model = [[PShowItemModel alloc] init];
model.top = @"1";
model.img = @"1";
[arr addObject:model];
model = [[PShowItemModel alloc] init];
model.top = @"2";
model.img = @"2";
[arr addObject:model];
PShowView * psView = [PShowView PShowViewWithFrame:CGRectMake(0, 70, 375, 300) Models:arr];
psView.backgroundColor = [UIColor grayColor];
[self.view addSubview:psView]; //添加到视图上
psView.isCanVertical = NO; //设置是否允许竖直方向先的拖动
[psView setBlock:^(PShowItemModel *model) {
NSLog(@"%s",__func__);
}];
- 如果有什么不对的地方,请留言提醒一下!!
接下来是代码的头文件与实现
- PShowView.h
#import <UIKit/UIKit.h>
#import "PShowItem.h"
typedef void(^clickItem)(PShowItemModel * model);
@interface PShowView : UIView
@property(nonatomic, assign) BOOL isCanVertical;
+ (instancetype)PShowViewWithFrame:(CGRect)frame Models:(NSArray *)arr;
-(void)setBlock:(clickItem)block;
@end
- PShowView.m
#import "PShowView.h"
@interface PShowView() <UIGestureRecognizerDelegate>
@property(nonatomic, strong) NSArray * models;
@property(nonatomic, strong) PShowItem * view1;
@property(nonatomic, strong) PShowItem * view2;
@property(nonatomic, strong) PShowItem * view3;
@property(nonatomic, strong) PShowItem * view4;
@property(nonatomic, strong) PShowItem * view5;
@property(nonatomic, assign) CGPoint view2Center;
@property(nonatomic, assign) CGPoint view3Center;
@property(nonatomic, assign) CGPoint view4Center;
@property(nonatomic, assign) CGFloat viewWidth;
@property(nonatomic, assign) CGFloat viewHeight;
@property(nonatomic, assign) CGRect bigBounds;
@property(nonatomic, strong) NSMutableArray * dataArr;
@property(nonatomic, assign) int moveCount;
@property(nonatomic, strong) clickItem block;
@end
@implementation PShowView
+ (instancetype)PShowViewWithFrame:(CGRect)frame Models:(NSArray *)arr{
PShowView * psView = [[PShowView alloc] initWithFrame:frame];
psView.models = arr;
return psView;
}
- (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor lightGrayColor];
[self addSubview:self.view1 = [[PShowItem alloc] init]];
[self addSubview:self.view2 = [[PShowItem alloc] init]];
[self addSubview:self.view3 = [[PShowItem alloc] init]];
[self addSubview:self.view4 = [[PShowItem alloc] init]];
[self addSubview:self.view5 = [[PShowItem alloc] init]];
self.dataArr = [NSMutableArray array];
[self layoutUI];
UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
pan.delegate = self;
[self addGestureRecognizer:pan];
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(view3tap)];
tap.delegate = self;
[self.view3 addGestureRecognizer:tap];
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(view2tap)];
tap.delegate = self;
[self.view2 addGestureRecognizer:tap];
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(view4tap)];
tap.delegate = self;
[self.view4 addGestureRecognizer:tap];
}
return self;
}
- (void)layoutUI{
self.viewWidth = (CGRectGetWidth(self.frame) - 30) / 2.0;
CGFloat height = CGRectGetHeight(self.frame);
if (self.viewWidth > height) {
self.viewWidth = height;
}
CGFloat topSpace = (height - self.viewWidth) / 2.0;
CGFloat leftSpace = (CGRectGetWidth(self.frame) / 2.0) - self.viewWidth;
self.view1.frame = CGRectMake(leftSpace, topSpace, self.viewWidth, self.viewWidth);
self.view2.frame = CGRectMake(leftSpace, topSpace, self.viewWidth, self.viewWidth);
self.view3.frame = CGRectMake(self.viewWidth/2.0 + leftSpace, topSpace, self.viewWidth, self.viewWidth);
self.view4.frame = CGRectMake(self.viewWidth + leftSpace, topSpace, self.viewWidth, self.viewWidth);
self.view5.frame = CGRectMake(self.viewWidth + leftSpace, topSpace, self.viewWidth, self.viewWidth);
self.view3Center = self.view3.center;
self.view2Center = self.view2.center;
self.view4Center = self.view4.center;
self.view1.alpha = 0;
self.view5.alpha = 0;
self.view2.alpha = 0.5;
self.view4.alpha = 0.5;
self.view3.alpha = 1;
// [self.view3.layer setAffineTransform:CGAffineTransformMakeScale(1.2, 1.2)];
[self bringSubviewToFront:self.view2];
[self bringSubviewToFront:self.view4];
[self bringSubviewToFront:self.view3];
[self sendSubviewToBack:self.view5];
self.view3.bounds = CGRectMake(0, 0, self.viewWidth * 1.2, self.viewWidth * 1.2);
self.bigBounds = self.view3.bounds;
}
- (void)setModels:(NSArray *)models{
_models = models;
self.moveCount = 0;
if (models.count > 0) {
for (int i = self.moveCount; i < self.moveCount + 5; i++) {
int index = i%models.count;
[self.dataArr insertObject:_models[index] atIndex:i];
}
[self setinfoToItem];
}
}
- (void)setinfoToItem{
[self.view1 setModel:self.dataArr[0]];
[self.view2 setModel:self.dataArr[1]];
[self.view3 setModel:self.dataArr[2]];
[self.view4 setModel:self.dataArr[3]];
[self.view5 setModel:self.dataArr[4]];
}
- (void)panAction:(UIPanGestureRecognizer *)pan{
CGPoint point = [pan translationInView:pan.view];
CGFloat MaxM = self.viewWidth/2.0;
if (fabs(point.x) >= MaxM) {
point.x = point.x/(fabs(point.x)) * MaxM;
}
CGFloat MaxH = (CGRectGetHeight(self.bounds) - self.viewWidth)/2.0;
if (fabs(point.y) >= MaxH) {
point.y = point.y/(fabs(point.y)) * MaxH;
}
if (!self.isCanVertical) {
point.y = 0;
}
self.view3.center = CGPointMake(self.view3Center.x + point.x, self.view3Center.y + point.y);
CGFloat moveBL = fabs(point.x) / MaxM;
CGRect frame = self.view3.bounds;
frame.size.width = (1.2- moveBL * 0.2 )*self.viewWidth;
frame.size.height = (1.2- moveBL * 0.2)*self.viewWidth;
self.view3.bounds = frame;
if (point.x > 0) {
self.view2.center = CGPointMake(self.view2Center.x + (point.x * 1), self.view2Center.y + point.y * 0.5);
self.view4.center = CGPointMake(self.view4Center.x , self.view4Center.y + point.y * 1.0);
self.view1.alpha = fabs(point.x)/MaxM/2.0;
self.view2.alpha = 0.5 + fabs(point.x)/MaxM/2.0;
self.view4.alpha = 0.5 - fabs(point.x)/MaxM/2.0;
self.view3.alpha = 1 - fabs(point.x)/MaxM/2.0;
CGRect frame = self.view2.bounds;
frame.size.width = (1 + moveBL * 0.2 )*self.viewWidth;
frame.size.height = (1 + moveBL * 0.2)*self.viewWidth;
self.view2.bounds = frame;
if (moveBL > 0.5) {
[self bringSubviewToFront:self.view2];
}else{
[self bringSubviewToFront:self.view3];
}
}else {
self.view4.center = CGPointMake(self.view4Center.x + (point.x * 1), self.view4Center.y + point.y * 0.5);
self.view2.center = CGPointMake(self.view2Center.x , self.view2Center.y + point.y * 1.0);
self.view5.alpha = fabs(point.x)/MaxM/2.0;
self.view4.alpha = 0.5 + fabs(point.x)/MaxM/2.0;
self.view2.alpha = 0.5 - fabs(point.x)/MaxM/2.0;
self.view3.alpha = 1 - fabs(point.x)/MaxM/2.0;
CGRect frame = self.view4.bounds;
frame.size.width = (1 + moveBL * 0.2 )*self.viewWidth;
frame.size.height = (1 + moveBL * 0.2)*self.viewWidth;
self.view4.bounds = frame;
if (moveBL > 0.5) {
[self bringSubviewToFront:self.view4];
}else{
[self bringSubviewToFront:self.view3];
}
}
if (pan.state == UIGestureRecognizerStateEnded) {
if (moveBL > 0.5) {
if (point.x < 0) {
[self view4tap];
}else{
[self view2tap];
}
}else{
[UIView animateWithDuration:0.1 animations:^{
[self layoutUI];
}];
}
}
}
- (void)moveToRight:(BOOL)rightB{
if (_models.count < 1) {
return;
}
if (rightB) {
self.moveCount--;
if (self.moveCount < 0) {
self.moveCount = (int)_models.count - 1; //当滑倒-1的时候,相当于所给的数组中最后一个元素添加的时候
}
[self.dataArr removeLastObject];
if (_models.count > 0) {
int index = (abs(self.moveCount)%_models.count);
[self.dataArr insertObject:_models[index] atIndex:0];
[self setinfoToItem];
}
}else{
self.moveCount++;
[self.dataArr removeObjectAtIndex:0];
if (_models.count > 0) {
int index = abs(self.moveCount + 4)%_models.count;
[self.dataArr addObject:_models[index]];
[self setinfoToItem];
}
}
}
- (void)view2tap{
[UIView animateWithDuration:0.1 animations:^{
[self bringSubviewToFront:self.view2];
self.view2.center = self.view3Center;
self.view2.bounds = self.bigBounds;
self.view3.center = self.view4Center;
self.view3.bounds = self.view4.bounds;
self.view1.alpha = 0.5;
self.view2.alpha = 1;
self.view3.alpha = 0.5;
self.view4.alpha = 0;
} completion:^(BOOL finished) {
[self moveToRight:YES];
[self layoutUI];
}];
}
- (void)view4tap{
[UIView animateWithDuration:0.1 animations:^{
[self bringSubviewToFront:self.view4];
self.view4.center = self.view3Center;
self.view4.bounds = self.bigBounds;;
self.view3.bounds = self.view2.bounds;
self.view3.center = self.view2Center;
self.view5.alpha = 0.5;
self.view4.alpha = 1;
self.view3.alpha = 0.5;
self.view2.alpha = 0;
} completion:^(BOOL finished) {
[self moveToRight:NO];
[self layoutUI];
}];
}
- (void)view3tap{
if (self.block) {
self.block(self.dataArr[2]);
}
}
@end
- PShowItem.h
#import <UIKit/UIKit.h>
@interface PShowItemModel : NSObject
@property(nonatomic, strong) NSString * title;
@property(nonatomic, strong) NSString * img;
@property(nonatomic, strong) NSString * top;
@end
@interface PShowItem : UIView
- (void)setModel:(PShowItemModel *)model;
- (void)setInfo:(NSString *)str;
@end
- PShowItem.m
#import "PShowItem.h"
@implementation PShowItemModel
@end
@interface PShowItem()
@property(nonatomic, strong) PShowItemModel * model;
@property(nonatomic, strong) UITextView * infoTV;
@property(nonatomic, strong) UIImageView * image;
@end
@implementation PShowItem
- (void)setFrame:(CGRect)frame{
[super setFrame:frame];
// 让子视图可以随着一起缩放
[self setAutoresizesSubviews:YES];
if (!self.image && frame.size.width > 0) {
self.image = [[UIImageView alloc] initWithFrame:self.bounds];
// 设置图片的随着父视图缩放的参数
self.image.autoresizingMask =
UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleBottomMargin ;
[self addSubview:self.image];
}
if (!self.infoTV && frame.size.width > 0) {
self.infoTV = [[UITextView alloc] initWithFrame:CGRectMake(10, 10, 60, 30)];
[self addSubview:self.infoTV];
/*
在这里添加所需要的控件 以及布局
*/
}
}
- (void)setModel:(PShowItemModel *)model{
_model = model;
[self.image setImage:[UIImage imageNamed:model.img]];
self.infoTV.text = model.top;
/*
在这里对布局的文件进行赋值调整
*/
}
- (void)setInfo:(NSString *)str{
self.infoTV.text = str;
}
@end