2017-09-03 18:09:22 Mo_Mo123 阅读数 3029
  • javascript零入门实战系列

    本套javascript从入门开始,课程采用大量案例讲解js在网站中的应用. 案例主要有大量的逻辑训练题,常见的网站特效,轮播,手风琴,选项卡,键盘控制物体运动,图片透明度,缓存运动,面向对象&闭包的应用等等

    31812 人正在学习 去看看 吴华

一般来说实现轮播图的基础控件有两个,UIScrollView或UICollectionView,二者选一,我更愿意用UICollectionView,至于原因,读者们发挥想象力吧,我只是在看轮播图的时候第一个就想到了UICollectionView,仅此而已。

既然第一个想到的是UICollectionView,那它对我来说应该就是最合适的。思考一下下面的问题,然后撸代码吧。


问题1
怎样实现顺滑的滚动,使得从最后一个右滑时很自然的显示第一个以及从第一个左滑时很自然的显示最后一个?

首先,我们来分析一下这个问题。
假设我们有n个item要轮播(n >= 1),之所以n不取0,是因为这样没什么意义。
分情况讨论:
1、n <= 1
这个情况最简单嘛,始终只显示一个item或者啥都不显示,既不需要左滑也不需要右滑。

2、n > 1
– 由问题“第一个item[0]向右滑动显示最后一个item[n-1]” 得出:item[0]之前有个item,它就是item[n-1]。
– 由问题“最后一个item[n-1]向左滑动显示第一个item[0]”得出:item[n-1]后面有个item,它就是item[0]。
UI上的item的顺序如下图
这里写图片描述

因此为了解决问题1,在设置items时我们得出了如下逻辑
if (items.count > 1) {
//在数组的头部插入最后一个item,在数组的尾部加上第一个item
//使得新的数组元素个数等于原数组元素个数+2
}

demo代码如下:

- (void)setItems:(NSArray *)items
{
    if (items.count > 1) {
        NSMutableArray  * arr = [items mutableCopy];
        [arr addObject:[items firstObject]];
        [arr insertObject:[items lastObject] atIndex:0];
        _items = arr;
    } else {
        _items = [items copy];
    }
}

问题2
怎样控制item切换间隔?

最容易想到的方式就是NSTimer啦,间隔timeSpace秒执行一次切换操作,滚动到下个item。
说起来容易,但是实现起来稍有麻烦,因为在解决问题1的时候咱们对items数组进行了修改,但是不要怕,因为原理很简单。下面分情况讨论一下:

1、从items[0]右滑切到items[n-1],如下图
这里写图片描述
当滚动结束,item[n-1]完全显示后,我们需要手动的修改collectionView的偏移量,显示红色框框的那个item[n-1]。
这个偏移量也很好计算width * ( _items.count - 2)

2、从items[n-1]左滑切到item[0],如下图
这里写图片描述
当滚动结束,item[0]完全显示后,我们也需要手动的修改collectionView的偏移量,显示红色框框的那个item[0]。
这个偏移量更容易看出来,就是width自己了

第二个问题也搞定了,还有什么问题呢?
到目前为止,搞定了这两个问题之后,一个简单的轮播图已经完成了。



然而,作为一枚追求完美的猿,怎么可以这样草草了事呢?而且做的又不是国企的项目~



优化1

添加一个小点点的控件,用来表示当前显示的是第几个item。

这个就是UIpageControl啦。

timer方法执行的时候,很好计算下一个要显示的哪个item,这种情况下设置currentPage并不难,所以在这里就略过了。

当手指滑动切换item的时候,我们也要得到将要显示的是哪个item,在此我要告诉你一个UIScrollView的代理方法

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(inout CGPoint *)targetContentOffset
{
    //targetContentOffset->x即为scrollView在x轴的目标偏移量
    //x/width就是目标索引了,但是要记得转化成实际的索引。
}

通过这个代理方法我们能预先知道collectionView将要停在哪里,这样的话我们只需要那这个坐标的x除以其宽度,就可以知道索引了。

详细的处理过程在这里就不说了,有兴趣的话可以看代码。文章最后我会放上代码链接。


优化2

timer控制的自动滚动方法与手势滚动的冲突

在这里我学习了网易云音乐的效果,实现方式如下:
当有手势的时候就把timer关掉;
当滚动完成后再启用timer;
为了让当前这个item显示时间达到timeSpace秒,使用了GCD的dispatch_after延迟timeSpace秒后fire timer。

此项优化会导致一个问题,如果连续滑动,会导致调用了好几次dispatch_after,导致所做的延迟没有意义。因此我使用了NSInvocationOperation来做相关控制,理由很简单,因为我可以随时cancel掉一个不想要的操作。


优化3

像网易云音乐一样,我不想用户滑得很快,在一个item还未显示完全就开始下一次的滑动

这个问题可以通过userInteractionEnabled这个属性控制。

最后附上代码地址,大家可以拿去直接用,当然点击回调代码中未实现,需要自行添加。喜欢的话记得star哦

2018-08-23 17:02:40 CQAHF 阅读数 147
  • javascript零入门实战系列

    本套javascript从入门开始,课程采用大量案例讲解js在网站中的应用. 案例主要有大量的逻辑训练题,常见的网站特效,轮播,手风琴,选项卡,键盘控制物体运动,图片透明度,缓存运动,面向对象&闭包的应用等等

    31812 人正在学习 去看看 吴华

 

pod 'SCAdView'

 

    SCAdView *adView = [[SCAdView alloc] initWithBuilder:^(SCAdViewBuilder *builder) {
        builder.adArray = arrayFromService;
        builder.viewFrame = (CGRect){0,100,self.view.bounds.size.width,self.view.bounds.size.width/2.f};
        builder.adItemSize = (CGSize){self.view.bounds.size.width/2.5f,self.view.bounds.size.width/4.f};
        builder.minimumLineSpacing = 0;
        builder.secondaryItemMinAlpha = 0.6;
        builder.threeDimensionalScale = 1.45;
        builder.itemCellNibName = @"SCAdDemoCollectionViewCell";
    }];

About SCAdViewBuilder

Please read SCAdViewBuilder's interface in SCAdView.hfile.

Effects

Horizontal scrolling

Vertical scrolling

SCAdView

前言

如果我的代码能帮助到你哪怕是一点点,请点一下star。谢谢你的支持,你的star是我的动力。

介绍

SCAdView是一个支持2D平面效果和3D缩放效果 , 可定制上下左右方向滚动 , 有限/无限循环 轮播的轮播控件

安装

手动安装

下载源代码并解压,将目录下SCAdView文件夹添加到你的项目中

CocoaPods

创建或在你的 podfile中添加:

pod 'SCAdView'

然后到终端cd到目录下执行 pod install

用法

在使用的时候,我们应该通过一个SCAdViewBuilder对象来构造出SCAdView,而我们可以通过在构造方法中修改buidler中的属性,来定制一个我们想要的 SCAdView
eg.

 

#pragma mark -水平模式
/**
 *  @brief 水平显示
 */
-(void)showAdHorizontally{
    SCAdView *adView = [[SCAdView alloc] initWithBuilder:^(SCAdViewBuilder *builder) {
        builder.viewFrame = (CGRect){0,0,Width,Height-SafeAreaTopHeight-Width*0.2};
        builder.adItemSize = (CGSize){Width/1.8,Height/2};
        builder.minimumLineSpacing = Width*0.1;
        builder.secondaryItemMinAlpha = 1.0;
        builder.threeDimensionalScale = 1.3;
        builder.itemCellNibName = @"SCAdDemoCollectionViewCell";
        builder.infiniteCycle =5.0f;
    }];
    adView.backgroundColor = [UIColor clearColor];
    adView.delegate = self;
    _adView = adView;
    [self.view addSubview:adView];
    UIBlurEffect* effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVisualEffectView* effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
    effectView.frame = CGRectMake(0, 0, Width, Height);
    [_bottomImgView addSubview:effectView];
}
#pragma mark -delegate
-(void)sc_didClickAd:(id)adModel{
    NSLog(@"sc_didClickAd-->%@",adModel);
    if ([adModel isKindOfClass:[HeroModel class]]) {
        NSLog(@"%@",((HeroModel*)adModel).imageName);
        if (_adView) {
            [_adView pause];
        }
        BaseWKWebviewVC * VC = [[BaseWKWebviewVC alloc]initWithUrl:[((HeroModel*)adModel).link_url HtmlToString]];
        PushVC(VC);
    }
}
-(void)sc_scrollToIndex:(NSInteger)index{
    NSLog(@"sc_scrollToIndex-->%ld",index);
    if (self.dataArray.count>index) {
        HeroModel*model = self.dataArray[index];
         [_bottomImgView SD_WebimageUrlStr:model.background_url placeholderImage:nil];
    }
}

 

 

SCAdViewBuilder 的详解

请到SCAdView.h文件查阅SCAdViewBuilder的 interface。

效果

https://www.jianshu.com/p/232a0b429f37

2015-11-17 16:14:11 techfu 阅读数 3077
  • javascript零入门实战系列

    本套javascript从入门开始,课程采用大量案例讲解js在网站中的应用. 案例主要有大量的逻辑训练题,常见的网站特效,轮播,手风琴,选项卡,键盘控制物体运动,图片透明度,缓存运动,面向对象&闭包的应用等等

    31812 人正在学习 去看看 吴华

   前言

          以前开发程序的时候需要使用图片轮播的效果,最开始的想法就是使用多少张图片就创建多少个UIImageView贴上去,当时确实也是这么做的,但是图片播放到最后一张的时候手动是没法直接切换到第一张图片的,这就给用户带来不好的体验,而且UIImageView创建多了,对性能也是有很大的影响的,所以潜心研究了下。

         啥也不多说了,直接上代码:https://github.com/zengqingf/ZQFCycleView 

原理:

      其实原理也很简单,就是放上三个UIImageView,默认的显示的是中间的UIImageView展示,当用户划到下一张图片的临界点时候,偷偷的切换回中间的UIImageView展示,但是UIImage却全部换掉了,也就是说用户永远看到的是中间的UIImageView,只是内容不同而已。如果你也觉得demo对你有用的话,千万不要忘记star哦!



      纯代码写出来的无限轮播图,可以轻松的使用第三方比如SDImage等异步加载轮播图上的图片


      作者的新浪微博是 @爱编程的小福子 记得关注我哦!


   开始使用ZQFCycleView

   创建轮播图

self.cycleView = [[ZQFCycleView alloc] initWithFrame:CGRectMake(0, 20, width, 180) delegate:self];
[self.view addSubview:_cycleView];

     实现代理方法

//返回图片的个数
- (NSInteger)countOfCycleView:(ZQFCycleView *)cycleView{
    return self.dataArr.count;
}
//设置imageview
- (void)cycleView:(ZQFCycleView *)cycleView willDisplayImageView:(UIImageView *)imageView index:(NSInteger)index{
    //如果需要网络加载,这里可以使用第三方,比如SDImage等等
    imageView.image = self.dataArr[index];
}
//滑动停止的时候显示标签
- (void)cycleView:(ZQFCycleView *)cycleView didDisplayTitleLabel:(UILabel *)titleLabel index:(NSInteger)index{
    titleLabel.text = [NSString stringWithFormat:@"当前的索引是:%ld", index];
}
//点击触发的
- (void)cycleView:(ZQFCycleView *)cycleView didTouchImageView:(UIImageView *)imageView  titleLabel:(UILabel *)titleLabel index:(NSInteger)index{
    NSLog(@"%@", [NSString stringWithFormat:@"当前点击的是:%ld", index]);
}

     开始播放

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.cycleView startPlayWithTimeInterval:5];//轮播图开始播放
}

      停止播放

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [self.cycleView stopPlay];//控制器消失的时候记得停止轮播图的定时器,否则可能出现内存泄露
}

2018-09-17 17:20:28 wcsandlili 阅读数 5711
  • javascript零入门实战系列

    本套javascript从入门开始,课程采用大量案例讲解js在网站中的应用. 案例主要有大量的逻辑训练题,常见的网站特效,轮播,手风琴,选项卡,键盘控制物体运动,图片透明度,缓存运动,面向对象&闭包的应用等等

    31812 人正在学习 去看看 吴华

好久没有写博客了,前段时间换了家公司,做了两个多星期,完成了一款app的开发, 公司没有app的需求了,我们几个移动端Android和IOS都转岗开发微信小程序,由于刚接触小程序不到两周,技术还是基于复制粘贴,h5以前也就看看,所以针对css样式和div之类的没有什么感觉,基本一切从0开始,好了,扯淡完毕-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

刚看了2天的小程序,咱们几个就开始上手开撸,不得不说微信的小程序封装的还是挺全面的,其实也就是间接的说很多东西都封装的比较死板,UI希望首页的banner实现各种形式的3D轮播图的效果,请看效果图

其实在app里面这种效果还是比较常见的,开源库也比较多,但是作为资深伸手党的我,居然没有搜索到实现3D轮播图的实例,好吧,只能自己开撸了,我的方式是基于原生的Swiper来实现的,配合previous-margin next-margin来实现左右两边的边框缩进效果,好了这只是第一步,第二部就是实现缩放的动画了效果了,我自己总结了两种方法,

第一种:通过css中控制选中和没有选中的swiper做监听,修改对应的css的样式,这时候需要对swpier做onChange监听,来改变选中的index角标,这个变量要写在data层里面,让直行img的时候能动态获取到xIndex的值,执行不同的css样式,这种方式通过设置img的高度来实现,选中设置100%的高度,没有选中的设置高度为90%,代码如下

 <view class='bannerWrap'>
    <image class='imgBannerBack' src='../../static/img/back_banner.png' mode='scaleToFill'></image>
    <swiper class='bannerSwiper' previous-margin="54rpx" next-margin='54rpx' indicator-dots="true" indicator-color='#B5B5B5' indicator-active-color='#fff' interval='3000' duration='500' bindchange='onChange' circular='true'>
      <block wx:for="{{banner}}">
        <swiper-item>
          <image class="{{index==xindex?'imageBanner':'imageBanner_small'}}" src="{{item}}" id='{{item.url}}' bindtap='imageClick'></image>
        </swiper-item>
      </block>
    </swiper>
  </view>



.imageBanner {
  width: 100%;
  height: 100%;
  border-top-left-radius: 20rpx;
  border-top-right-radius: 20rpx;
}


.imageBanner_small {
  width: 94%;
  height: 90%;
  margin-left: 20rpx;
  margin-right: 20rpx;
  position: absolute;
  bottom: 0;
  border-top-left-radius: 15rpx;
  border-top-right-radius: 15rpx; 

}










第二种方法:

原理基本相同,只不过改变图片大小的时候利用的css的trasnform和trasnsition来实现界面动画的放大和缩小的过程的一个切换,具体代码就是css的样式做了一个切换

具体代码如下

.imageBanner {
  width: 100%;
  height: 100%;
  border-top-left-radius: 20rpx;
  border-top-right-radius: 20rpx;
}

.imageBanner_small {
  height: 100%;
  transform: scale(0.9);
  transition: all 0.2s ease-in 0s;
  border-top-left-radius: 15rpx;
  border-top-right-radius: 15rpx;
  bottom: -13rpx;
  margin-left: -10rpx;
  position: absolute;
 
}

下面看下具体实现的效果图吧

今天比较忙,等稍微闲点的时候将对应的demo会上传供各位大佬参考,刚刚做小程序,实现的效果可能比较low,但是能解决目前遇到的问题,如果哪位大佬有更加好的实现方式,希望不吝赐教!

终于在一位兄弟的督促下把demo上传了,贴上地址

https://github.com/WinWang/WeChatBanner/tree/master

2016-01-25 17:33:01 m372897500 阅读数 2578
  • javascript零入门实战系列

    本套javascript从入门开始,课程采用大量案例讲解js在网站中的应用. 案例主要有大量的逻辑训练题,常见的网站特效,轮播,手风琴,选项卡,键盘控制物体运动,图片透明度,缓存运动,面向对象&闭包的应用等等

    31812 人正在学习 去看看 吴华

m

平时APP中的广告位或者滚动的新闻图片等用到的就是图片轮播这种效果,实现方式主要有两种,一种是ScrollView+ImageView,另一种则是通过CollectionView,今天总结的是ScrollView这种方式。

    1.图片轮播效果实现

      主要实现思路是:根据图片总数及宽高设置好ScrollView的大小,每切换一张图片相当于在ScrollView上进行一个图片宽度的移动行为,并加入定时器,实现自动轮播。

      如图所示,设置好ScrollView及PageControl,ScrollView的contentSize根据图片数量确定,注意启用pagingEnabled这个属性,确保整页移动,同样pageControl也是根据图片数量来确定,每一页代表一张图片。

contentOffset更新页码。

     定时器设置,这里设置为每隔2秒滚动更新一次,实际上就是每隔2秒更新一次页码,根据页码的变化,让ScrollView跟着移动,每次移动一张图片的距离

     这里还需要注意的是,由于加入定时器有自动轮播的效果了,会与手动拖拽ScrollView冲突,即手动拖拽ScrollView过程时ScrollView可能自动移动更新图片了,显然这种效果是不符合用户习惯的,这时需要在ScrollView的代理事件中进行处理,即开始拖拽ScrollView时停止定时器,拖拽结束后再开启定时器。

      那到这里是不是就结束了呢?我们看看效果图:

      这里有两个问题:

     (1)首先是移动到最后一张图片时无法移动了,如果是制作APP的新特性页面,这样的滚动效果已经可以了,但如果在广告位或者是滚动新闻这些场景下这种效果是不够好的,一般滚动到最后一张图片时,继续拖拽都会移动到第一张图片,实现一种滚动循环效果。

     (2)定时器自动轮播图片时,确实图片循环轮播了,但是仔细看会发现,ScrollView是由最后一种图片位置生硬得拉回到第一张图片的位置,效果也不够理想。

      解决办法下面接着说。

    2.图片轮播无限循环效果实现

      刚刚说到第一个问题,ScrollView移动到最后一张图片时无法移动了,这是因为ScrollView已经移动到最后,而图片又是依次排列,自然也就无法移动。

      解决办法是,我们换一个思路实现图片轮播效果,ScrollView上只放三个ImageView,屏幕始终显示中间的ImageView,左边和右边的ImageView分别代表前一张图片和后一张图片,屏幕移动的时候,中间的ImageView变化,同时左右两边的ImageView也随之变化,两种边界情况:

      (1)当屏幕显示最后一张图片时,右边的ImageView也即下一站图片应该是最开始的第一张图片;

      (2)当屏幕显示最开始的第一张图片时,左边的ImageView也即上一张图片应该是最后一张图片。

      这样三个ImageView不断变化就造成一种图片轮播无限循环的效果。 参考:http://www.cnblogs.com/kenshincui/p/3913885.html

      相对于之前的效果,有一些改变,主要有:

      (1)ScrollView只需要设置三个ImageView即可,并且默认显示中间的ImageView

      (2)根据ScrollView的移动情况,迅速变化三个ImageView中图片数据

 

       (3)ImageView更新完毕后,偷偷把ScrollView拉回到中间的ImageView位置,这样视觉效果上就实现了无限循环的效果

 

      效果图:

 

      但是,这里在加入定时器后实现图片轮播自动循环时遇到了问题,主要是初始化显示第一张图片与根据定时器设置自动移动ScrollView有一些冲突,在code4App上找到其他人一个工程,采用的思路相同,单独封装了ScrollView进行处理,已经解决该问题。

可参考:http://code4app.com/ios/AdScrollerView/54955a78933bf0f2168b45b4


iOS 3D卡片式轮播

阅读数 22648

没有更多推荐了,返回首页