iOS实现卡片式滚动效果 iOS实现电影选片效果

本文实例为大家分享了iOS实现卡片式滚动效果的具体代码,供大家参考,具体内容如下

先来张效果图吧:

直接上源码了就(工作比较忙,就不一一解释了,有问题可以Q一同讨论,793136807):

CardScrollView.h

#import <UIKit/UIKit.h>

@interface CardView : UIView

@property (nonatomic, assign) CGFloat zoomRate;

@property (nonatomic, strong) NSString *imgUrl;

- (UIImage *)getImage;

@end

@interface CardScrollView : UIView

@property (nonatomic, assign) CGFloat cardViewWidth;
@property (nonatomic, assign) CGFloat minCardZoomRate;
@property (nonatomic, assign) CGFloat maxCardZoomRate;

@property (nonatomic, assign) BOOL needBackgroundBlurImage;

- (void)setImgUrls:(NSArray<NSString *> *)imgUrls selectedCard:(void(^)(NSInteger selectedIndex))selectedCard;

@end

CardScrollView.m

#import "CardScrollView.h"

@interface CardView ()

@property (nonatomic, strong) UIImageView *imgView;

@end

@implementation CardView

- (instancetype)initWithFrame:(CGRect)frame {
 if (self = [super initWithFrame:frame]) {
  _imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame))];
  [_imgView setContentMode:UIViewContentModeScaleAspectFit];
  [_imgView setClipsToBounds:YES];
  [self addSubview:_imgView];
 }
 return self;
}

- (void)setZoomRate:(CGFloat)zoomRate {
 if (zoomRate < 0) {
  zoomRate = 0;
 }
 _zoomRate = zoomRate;
 CGFloat width = CGRectGetWidth(self.bounds);
 CGFloat height = CGRectGetHeight(self.bounds);
 CGFloat imgViewWidth = width * zoomRate;
 CGFloat imgViewHeight = height * zoomRate;
 _imgView.frame = CGRectMake((width - imgViewWidth) / 2, (height - imgViewHeight) / 2, imgViewWidth, imgViewHeight);
}

- (void)setImgUrl:(NSString *)imgUrl {
 _imgUrl = imgUrl;
 [_imgView setImage:[UIImage imageNamed:imgUrl]];
}

- (UIImage *)getImage {
 return [_imgView image];
}

@end

@interface CardScrollView () <UIScrollViewDelegate>

@property (nonatomic, strong) UIImageView *bgImageView;
@property (nonatomic, strong) UIVisualEffectView *blurView;

@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, assign) CGFloat aroundSpacing;
@property (nonatomic, strong) NSArray<NSString *> *imgUrls;
@property (nonatomic, strong) NSMutableArray<CardView *> *cardViewArray;
@property (nonatomic, assign) NSInteger currentIndex;

@property (nonatomic, strong) void(^selectedCard)(NSInteger);

@end

@implementation CardScrollView

- (UIImageView *)bgImageView {
 if (!_bgImageView) {
  _bgImageView = [[UIImageView alloc] initWithFrame:self.bounds];
 }
 return _bgImageView;
}

- (UIVisualEffectView *)blurView {
 if (!_blurView) {
  [self addSubview:self.bgImageView];
  _blurView = [[UIVisualEffectView alloc] initWithFrame:self.bounds];
  [_blurView setEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
 }
 return _blurView;
}

- (UIScrollView *)scrollView {
 if (!_scrollView) {
  _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
  _scrollView.delegate = self;
  [_scrollView setShowsHorizontalScrollIndicator:NO];
 }
 return _scrollView;
}

- (NSMutableArray<CardView *> *)cardViewArray {
 if (!_cardViewArray) {
  _cardViewArray = [NSMutableArray array];
 }
 return _cardViewArray;
}

- (void)layoutSubviews {
 [super layoutSubviews];
 if (_needBackgroundBlurImage) {
  [self addSubview:self.blurView];
 }
 [self addSubview:self.scrollView];
}

- (void)setImgUrls:(NSArray<NSString *> *)imgUrls selectedCard:(void (^)(NSInteger))selectedCard {
 _imgUrls = imgUrls;
 _selectedCard = selectedCard;
 [self layoutCardViews];
}

- (void)layoutCardViews {
 if (_cardViewWidth == 0) {
  _cardViewWidth = CGRectGetWidth(self.bounds) / 2;
 }
 if (_minCardZoomRate == 0) {
  _minCardZoomRate = 0.5;
 }
 if (_maxCardZoomRate == 0) {
  _maxCardZoomRate = 1;
 }
 _aroundSpacing = (CGRectGetWidth(self.bounds) - _cardViewWidth) / 2;
 for (int i = 0; i < [_imgUrls count]; i++) {
  CardView *cardView = [[CardView alloc] initWithFrame:CGRectMake(_aroundSpacing + i * (_cardViewWidth), 0, _cardViewWidth, CGRectGetHeight(self.bounds))];
  cardView.zoomRate = _minCardZoomRate;
  cardView.imgUrl = _imgUrls[i];
  cardView.tag = i;
  UITapGestureRecognizer *tapGr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickCardView:)];
  [cardView addGestureRecognizer:tapGr];
  [_scrollView addSubview:cardView];
  [self.cardViewArray addObject:cardView];
 }
 [_scrollView setContentSize:CGSizeMake(CGRectGetMaxX([_cardViewArray lastObject].frame) + _aroundSpacing, 0)];
 [self setCardViewZoomRate:[_cardViewArray firstObject]];
 [self selectIndex:0];
}

- (void)clickCardView:(UIGestureRecognizer *)gestureCognizer {
 [self selectIndex:gestureCognizer.view.tag];
}

- (void)selectIndex:(NSInteger)index {
 _currentIndex = index;
 CardView *cardView = _cardViewArray[index];
 [_scrollView setContentOffset:CGPointMake(CGRectGetMidX(cardView.frame) - CGRectGetWidth(_scrollView.frame) / 2, 0) animated:YES];
 if (_needBackgroundBlurImage) {
  [_bgImageView setImage:[cardView getImage]];
 }
 if (_selectedCard) {
  _selectedCard(index);
 }
}

#pragma mark - 根据 CardView 在 X 轴的中心坐标 设置其 ZoomRate
- (void)setCardViewZoomRate:(CardView *)cardView {
 CGFloat offsetRate = ABS(_scrollView.contentOffset.x + CGRectGetWidth(_scrollView.frame) / 2 - CGRectGetMidX(cardView.frame)) / _cardViewWidth;
 CGFloat zoomRate = _maxCardZoomRate - offsetRate;
 if (zoomRate < _minCardZoomRate) {
  zoomRate = _minCardZoomRate;
 }
 [_scrollView bringSubviewToFront:cardView];
 [cardView setZoomRate:zoomRate];
}

#pragma mark - UIScrollView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
 NSInteger index = floorf((scrollView.contentOffset.x - _aroundSpacing + CGRectGetWidth(_scrollView.frame) / 2) / _cardViewWidth);
 if (index < 0) {
  index = 0;
 }
 if (index > [_cardViewArray count] - 1) {
  index = [_cardViewArray count];
 }
 [self setCardViewZoomRate:_cardViewArray[index]];
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
 int index = (scrollView.contentOffset.x - _aroundSpacing + CGRectGetWidth(_scrollView.frame) / 2) / _cardViewWidth;
 [self selectIndex:index];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
 if (!decelerate) {
  [self scrollViewDidEndDecelerating:scrollView];
 }
}

@end

使用:ViewController.m

#import "ViewController.h"
#import "CardScrollView.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutlet CardScrollView *cardScrollView;
//@property (nonatomic, strong) CardScrollView *cardScrollView;

@property (nonatomic, strong) NSMutableArray<NSString *> *imgUrls;

@end

@implementation ViewController

- (NSMutableArray<NSString *> *)imgUrls {
 if (!_imgUrls) {
  _imgUrls = [NSMutableArray array];
  for (int i = 0; i < 9; i++) {
   [_imgUrls addObject:[NSString stringWithFormat:@"%d", i + 1]];
  }
 }
 return _imgUrls;
}

//- (CardScrollView *)cardScrollView {
// if (!_cardScrollView) {
//  _cardScrollView = [[CardScrollView alloc] initWithFrame:self.view.bounds];
//  _cardScrollView.cardViewWidth = 150;
//  _cardScrollView.needBackgroundBlurImage = YES;
// }
// return _cardScrollView;
//}

- (void)viewDidAppear:(BOOL)animated {
 [super viewDidAppear:animated];
// [self.view addSubview:self.cardScrollView];
 [_cardScrollView setImgUrls:self.imgUrls selectedCard:^(NSInteger selectedIndex) {

 }];
}

@end

我一般习惯Storyboard开发,所以这里就使用的Storyboard拖拽的,代码中注释掉的 是纯代码使用的方法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • iOS实现无限循环滚动的TableView实战教程

    前言 本文主要给大家介绍了如何实现一个可以无限循环的TableView的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍吧. 先来看看效果: 思路 条条大路通罗马,个人分析下以下思路的可行性: 1.借鉴无限广告轮播的思路.可行性不高,主要是列表头部和尾部的衔接不够自然,而且快速滑动不够流畅. 2.使用TableView+3倍长度dataSource.可行性一般,在使用过程中滑动流畅,但是由于重复的数据源,可能导致在处理事件时需要特别对数据进行处理避免重复,另外此方法不能重用,总让有强迫

  • iOS仿网易新闻滚动导航条效果

    本文实例为大家分享了iOS滚动导航条效果展示的具体代码,供大家参考,具体内容如下 实现效果 效果:选择不同的栏目,下面出现不同的视图,栏目条可以滚动:下面的视图也可以滚动,滚动时上面对应的栏目要选中颜色为红色: 滚动的导航条包括两部分:标题滚动视图(UIScrollView),内容滚动视图(UIScrollView) 实现代码 1.首先实现Main.storyboard 2.创建多个子控制器:头条.科技.汽车.体育.视频.图片.热点 // 头条ViewController, 其它控制器和这个控制

  • IOS中无限滚动Scrollview效果

    本文实例讲了IOS无限滚动效果,分享给大家供大家参考,具体内容如下 滑动到当前位置时候才去请求,本地有内容则直接显示(以来SDWebImage,UIView+Ext) HZScrollView.h #import <UIKit/UIKit.h> typedef void(^HZReturnBlock)(NSInteger index,CGFloat offset); typedef NS_ENUM(NSUInteger, HZScrollViewPageControllPosition) {

  • iOS使用UICollectionView实现横向滚动照片效果

    本文实例为大家分享了iOS使用UICollectionView实现横向滚动展示照片的具体代码,供大家参考,具体内容如下 这是Demo链接 效果图 思路 1. 界面搭建 界面的搭建十分简单,采用UICollectionView和自定义cell进行搭建即可. // ViewController.m // 下面使用到的宏和全局变量 #define ScreenW [UIScreen mainScreen].bounds.size.width #define ScreenH [UIScreen main

  • iOS利用UIScrollView实现无限滚动效果

    前言 众所周知UIScrollView 的无限滚动主要应用在图片轮播器.欢迎界面等场景.它的原理是在要显示的图片前后各加一张图片即在第一张图片之前放最后一张图片,在最后一张图片之后放第一张图片,然后在滚动到边缘的时候,巧妙的过渡一下就可以"瞒天过海","以假乱真"的造成无限滚动的假象.网络上有很多只用三张或两张图片实现的方法,效率比这个方法高,但实现起来稍微麻烦一点,有兴趣的可以去深入研究. 实现步骤 1.根据需求准备几张图片,在网上找了5张图片,分别命名为 img

  • iOS UIScrollView滚动视图/无限循环滚动/自动滚动的实例代码

    我们都知道UIScrollView有一种很流畅的切换效果,结合UIPageControl的辅助展示效果,就可以完成一个很不错的产品介绍功能页面.下面给大家分享iOS UIScrollView滚动视图/无限循环滚动/自动滚动功能,具体代码如下所示: <UIScrollViewDelegate> #define WIDTH [[UIScreen mainScreen] bounds].size.width #define HEIGHT [[UIScreen mainScreen] bounds].

  • iOS实现类似格瓦拉电影的转场动画

    用过格瓦拉电影,或者其他app可能都知道,一种点击按钮用放大效果实现转场的动画现在很流行,效果大致如下 自定义转场动画 首先就要声明一个遵守UIViewControllerAnimatedTransitioning协议的类. 然后实现协议中的两个函数 // This is used for percent driven interactive transitions, as well as for container controllers that have companion animati

  • iOS实现滚动字幕的动画特效

    效果图 开始上代码 滚动字幕的原理是用timer定时器间隔一定的时间来驱动scrollView上的内容偏移,来实现滚动的效果,原理比较简单,关键是有些细节需要处理好,实现流畅效果的同时要考虑到性能优化 这里是.h文件的接口方法及属性,可适应大部分自定义场景 /*初始化*/ -(instancetype)initWithFrame:(CGRect)frame textArray:(NSArray *)textArray colorArray:(NSArray *)textColorArray; /

  • iOS实现卡片式滚动效果 iOS实现电影选片效果

    本文实例为大家分享了iOS实现卡片式滚动效果的具体代码,供大家参考,具体内容如下 先来张效果图吧: 直接上源码了就(工作比较忙,就不一一解释了,有问题可以Q一同讨论,793136807): CardScrollView.h #import <UIKit/UIKit.h> @interface CardView : UIView @property (nonatomic, assign) CGFloat zoomRate; @property (nonatomic, strong) NSStri

  • iOS实现3D卡片式轮播效果

    本文实例为大家分享了iOS实现3D卡片式轮播效果的具体代码,供大家参考,具体内容如下 效果: 参考UITableView的UITableViewDataSource和UITableViewDelegate两个方法实现:支持五险轮播,可以加载本地图片,也可以加载网络图片,可以根据自己的需求自定义 Demo地址 UITableViewDelegate /** * 当前显示cell的Size(中间页显示大小) * * @param flowView <#flowView description#>

  • js实现卡片式项目管理界面UI设计效果

    这是一款非常有创意的卡片式项目管理界面UI设计效果.该UI设计中,将各个项目以卡片的方式堆叠排列在屏幕上,当点击了其中的某个项目的时候,该项目图片会全屏放大,向下滚动鼠标可以看到该项目的介绍信息. 该项目管理界面还提供了一个全屏的导航菜单,用户可以通过右上角的汉堡包图标来触发全屏菜单. 使用方法 HTML结构 该卡片式项目管理界面的HTML结构分为3个部分:.cd-nav-trigger是全屏菜单的触发按钮,nav.cd-primary-nav是全屏导航菜单,.cd-projects-conta

  • iOS中无限循环滚动简单处理实现原理分析

    说下原理: 1./*初始化/ + (instancetype)loopScrollViewWithFrame:(CGRect)frame; 将背景collectinview视图初始化设置 代理和数据源 . 布局 2.在激活initwithFrame后触发 layoutSubviews //默认滚动到要显示的第一张图片 if (self.imageCollectionView.contentOffset.x == 0) { NSIndexPath *indexPath = [NSIndexPath

  • 在IOS系统上滚动条滚动到指定的位置出现空白页面的解决方案

    原因: -webkit-overflow-scrolling:touch 解释: 由于使用-webkit-overflow-scrolling这个属性,苹果手机会使用硬件加速,从而促使页面滑动得更加流畅,然而也导致了页面出现空白的情况. 解决办法: 滚动之前,先设-webit-overflow-scrolling的属性值为auto,然后页面滚动完了,再设为touch即可. 实例: $("#id").css('-webkit-overflow-scrolling','auto'); $(

  • Android仿探探卡片式滑动效果实现

    前言 第一次进入探探软件界面,就被这种通过卡片式滑动来选择"喜欢/不喜欢"的设计所吸引了.当时就非常想通过自己来实现这种仿探探式的效果,然而却没什么思路.不过毋庸置疑的是,这种效果的原理肯定和 ListView / RecyclerView 类似,涉及到 Item View 的回收和重用,否则早就因为大量的 Item View 而 OOM 了. 再到后来,看到许多大神也推出了同样仿探探效果的博客,从头到尾阅读下来,写得通俗易懂,基本上没什么问题.于是,实现仿探探效果的想法再次出现在脑海

  • iOS开发中TableView类似QQ分组的折叠与展开效果

    类似QQ分组的样子,实现tableView的折叠与展开.其实要做这个效果我先想到的是在tableView中再嵌套多个tableView,这个想法实现起来就有点难了. 所以还是换个思路,把tableView的HeaderView用上了.给headerView加上手势,轻松解决折叠展开的问题. 直接上代码吧. @property (nonatomic, strong) UITableView *myTableView; @property (nonatomic, strong) NSMutableA

  • RecyclerView+CardView实现横向卡片式滑动效果

    现在来介绍两种控件RecyclerView和CardView,并通过实例将它们结合在一起实现一种横向卡片式滑动效果. 1.RecyclerView RecyvlerView是android SDK 新增加的一种控件,也被官方推荐代替ListView来使用,因为其具有更好的灵活性和代替性. 2.CardView CardView是安卓5.0推出的一种卡片式控件,内部封装了许多有用的方法来实现美观效果. 3.如何使用RecylerView和CardView在android studio中 在buil

  • vue卡片式点击切换图片组件使用详解

    本文实例为大家分享了vue卡片式点击切换图片组件,供大家参考,具体内容如下 因为公司业务的问题,最近在写vue项目,有了一个卡片图片的点击的需求,自己又不想写动画效果,就偷个懒,采用vue是以数据驱动的原理,写了一个不太完整的vue组件,为了简单,就直接上代码吧 全部代码 未进行props传参设置,以后完善(简单最好嘛) <template> <!-- *以数据驱动的card式展示图片(无动画效果) * --> <div class="cardBanner"

  • cmake ios终端下执行提示错误 iOS version not found, tested: [5.0;5.1;6.0;6.1;7.0;8.3]的解决方案

    先给大家简单说下CMake. CMake是一个比make更高级的编译配置工具,它可以根据不同平台.不同的编译器,生成相应的Makefile或者vcproj项目. 通过编写CMakeLists.txt,可以控制生成的Makefile,从而控制编译过程. CMake自动生成的Makefile不仅可以通过make命令构建项目生成目标文件,还支持安装(make install).测试安装的程序是否能正确执行(make test,或者ctest).生成当前平台的安装包(make package).生成源码

随机推荐