从对轮播图的封装中体会 面对接口 编程的思想

.h 文件的内容:

#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface MFCyclmage : UIView
// 私有属性, 可以对外公开, 使用readonly
// 一般让别人去修改这个属性的属性(不能修改这个属性)
@property (nonatomic, strong, readonly) UIScrollView *cycleScrollView;
@property (nonatomic, strong, readonly) UIPageControl *imagePage;
// 初始化
// 相关于图片的数组
// 第一种赋值方式, 通过setter方法
@property (nonatomic, strong) NSArray *imagesArray;
// 第二种赋值方式, 自定义方法
- (void)setImageWithArray:(nonnull NSArray *)array;
@end
NS_ASSUME_NONNULL_END

.m 文件的内容:

#import "MFCyclmage.h"

@interface MFCyclmage ()<UIScrollViewDelegate>
@property (nonatomic, strong) UIScrollView *cycleScrollView;
@property (nonatomic, strong) UIPageControl *imagePage;
@end

@implementation MFCyclmage
#pragma mark -- scrollView Delegate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    // 改变pageController的对应下标
    NSInteger page = scrollView.contentOffset.x / self.bounds.size.width;
    _imagePage.currentPage = page - 1;
    if (page == 0) {
        // 改变滚动视图的下标
        _cycleScrollView.contentOffset = CGPointMake(self.bounds.size.width * (_imagesArray.count - 2), 0);
        _imagePage.currentPage = _imagePage.numberOfPages - 1;
    } else if (page == _imagesArray.count - 1) {
        _cycleScrollView.contentOffset = CGPointMake(self.bounds.size.width, 0);
        _imagePage.currentPage = 0;
    }
}
#pragma mark - initWithFrame
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%
        // 子控件初始化时, frame不要与初始化方法的frame一样
        // 推荐使用self.bounds / CGRectMake(0, 0, frame.size.width, self.size.height)
        //%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
        _cycleScrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
        [self addSubview:_cycleScrollView];
        [self initCycleScrollView];
        [self createImagePage:frame];
    }
    return self;
}
- (void)initCycleScrollView {
    _cycleScrollView.backgroundColor = [UIColor blackColor];
    _cycleScrollView.bounces = NO;
    _cycleScrollView.pagingEnabled = YES;
    _cycleScrollView.showsHorizontalScrollIndicator = NO;
    _cycleScrollView.delegate = self;
}
- (void)createImagePage:(CGRect)frame {
    _imagePage = [[UIPageControl alloc] initWithFrame:CGRectMake(0, 0, frame.size.width / 3, 20)];
    [self addSubview:_imagePage];
    _imagePage.numberOfPages = 5;
    _imagePage.center = CGPointMake(frame.size.width / 2, frame.size.height - 20 / 2);
    [_imagePage addTarget:self action:@selector(imagePageChange:) forControlEvents:UIControlEventValueChanged];
}
- (void)imagePageChange:(UIPageControl *)page {
    [_cycleScrollView setContentOffset:CGPointMake((page.currentPage + 1) * self.bounds.size.width, 0) animated:YES];
}

#pragma mark -- ImageArray
- (void)setImageWithArray:(NSArray *)array {
    // 根据传过来的数组, 进行处理, 生成图片数组
    NSArray *imageArray = [self handleArray:array];
    // 逻辑判断时, 用到的数组内容
    self.imagesArray = [NSArray arrayWithArray:imageArray];
    // 根据图片数组, 生成对应得imageView
    [self createAllImagesWithImageArray:imageArray];
    // 根据图片数组生成对应的视图
    _imagePage.numberOfPages = array.count;
    _cycleScrollView.contentSize = CGSizeMake(imageArray.count * self.bounds.size.width, 0);
    // 因为添加了最后一张图, 要让轮播图看起来在第一张
    _cycleScrollView.contentOffset = CGPointMake(self.bounds.size.width, 0);

    }
- (NSArray *)handleArray:(NSArray *)array {
    // 判断array元素的数据类型(不知道别人使用你的类的时候传进来的类型是什么)
    id firstObject = [array firstObject];
    // 最终的图片数组
    NSMutableArray *imageArray = [NSMutableArray array];
    // 判断对象是不是某种类型 isKindOfClass
    if ([firstObject isKindOfClass:[NSString class]]) {
        // 把 字符串 数组 转成 图片 数组
        for (NSString *imageName in array) {
            UIImage *image = [UIImage imageNamed:imageName];
            [imageArray addObject:image];
        }

    } else if ([firstObject isKindOfClass:[UIImage class]]) {
        // 这个方法用不可变数组将自己转为可变数组
        [imageArray setArray:array];
    }
    // 获取到第一张图
    UIImage *firstimage = [imageArray firstObject];
    // 获取到最后一张图
    UIImage *lastImage = [imageArray lastObject];
    // 下标为0的位置放最后一张图
    [imageArray insertObject:lastImage atIndex:0];
    // 在最后添加一张图
    [imageArray addObject:firstimage];
    // 用copy可以直接将可变的数组变为不可变的, 类比mutablecopy
    return [imageArray copy];
}
- (void)createAllImagesWithImageArray:(NSArray *)imageArray {
    // 使用数组创建imageView
    for (int i = 0; i < imageArray.count; i++) {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(i * self.bounds.size.width, 0, self.bounds.size.width, self.bounds.size.height)];
        imageView.image = imageArray[i];
        [_cycleScrollView addSubview:imageView];
    }
}
@end
时间: 2024-10-18 09:35:54

从对轮播图的封装中体会 面对接口 编程的思想的相关文章

iOS: 无限循环轮播图简单封装

轮播图思路: 1.首先要有一个ScrollView和两张图片,把图片放到ScrollView上. 2.要想滚动ScrollView的宽度需设置屏宽的2倍. 3.循环滚动,当滚动到最后一张图片时,采用偏移的方法,将偏移量归零,回到第一张图片. 4.将第二张的图片上的所有值赋给第一张图片. 5.设置让它自己滚动,需添加定时器. 需要的第三方数据库:SDWebImage m.文件内: #imporst "ScrollView.h" @interface ScrollView ()<UI

jQuery轮播图函数封装

函数调用的时候,传递四个必要的参数就行了.参数1:要运动的ul:参数2:左边按钮:参数3:右边按钮:参数4:运动速度:(可选,默认3s) 代码如下: html部分: <div class="div1">  <ul class="ul1">      <li>1111111111</li>         <li>2222222222</li>         <li>33333333

原生JS面向对象思想封装轮播图组件

原生JS面向对象思想封装轮播图组件 在前端页面开发过程中,页面中的轮播图特效很常见,因此我就想封装一个自己的原生JS的轮播图组件.有了这个需求就开始着手准备了,代码当然是以简洁为目标,轮播图的各个功能实现都分别分为不同的模块.目前我封装的这个版本还不适配移动端,只适配PC端. 主要的功能有:自动轮播,点击某一张图片对应的小圆点就跳转到指定图片,有前后切换按钮.使用的时候只需要传入图片的路径以及每张图片分别所对应的跳转路径还有目标盒子ID就可以了,还可以自定义每张图轮播的延时,不过延时参数不是必须

解决ionic2/ionic3轮播图切换页面或者点击过后不自动轮图

我们在ionic2/ionic3开发的过程中会出现切换页面或者滑动切换轮播图出现轮播图不再轮播的情况,这其实需要一些配置. 首先在运用到轮播图的component中引入 import {ViewChild } from '@angular/core'; import { Slides } from 'ionic-angular'; 然后 @ViewChild(Slides) slides: Slides; //解决切换其他页面回去轮播图不动问题 ionViewWillEnter(){ this.

IOS 封装轮播图

轮播图为一种常见的方式,常用于各种网站,或者App中,当然,作为APP的启动视图也是不错的选择. 闲时封装了一个,仅供新手参考. 1.新建工程,建立轮播图类 建立一个空的工程,新建一个类,起名为Carousel,继承于UIView 2.编写Carousel类接口 1 @interface Carousel : UIView 2 typedef NS_ENUM(NSInteger,UICarouselPageType){ 3 //建立一个枚举型,来设置Carousel的样式 4 UICarouse

初识 swift 封装轮播图

一.简介 换了一家公司.换了一个环境刚开始来公司自然不能有一丝一毫的放松,每天即使是没有什么工作也是看看这个博客.那个源码.尽量让自己更充实.慢慢的开始写几篇博客记录下自己遇到的一些问题和解决方法.其实也没什么就是瞎写没有什么思路反正就是遇到问题然后解决掉.最后分享出去. 随着工作走向正规公司的项目不是那么赶.也就有时间尝试一些新的东西.只是不想刚开始编程哪会那么激进今天学这个明天学那个了.APPLE 发布 swift 有一年多了.不能说好也不能说不好.总之没有了解过时没有话语权的.所以就想试试

用原生js封装轮播图

原生js封装轮播图 对于初学js的同学来说,轮播图还是一个难点,尤其是原生js封装轮播图代码,下面是我之前做的一个轮播图项目中封装好的一些代码,有需要的同学可以看一下,有什么不懂的可以看注释,注释看不懂的可以直接私信我 slide.js /* * 轮播图 */ function Slide(elem, ms, d, ind){ this.el = elem; this.w = parseInt(getStyle(elem, "width")); this.h = parseInt(ge

如何用面向对象的思维去封装一个小型轮播图插件

1.面向对象与面向过程 既然说到面向对象的思维,那就免不了要对面向过程的编程思维与面向对象的思维做一番比较. 笔者有 一段时间天真的认为有一个类,然后new一个对象就是面向对象编程了,现在想想还是太naive了呀. 其实面向对象的编程思维和面向过程的编程思维重要的不是对象和过程,而是思维. 比如说在生活中我们要做一道西红柿炒鸡蛋,很多人的第一反应就是西红柿炒鸡蛋第一步.第二步.第三步应该怎么做,每一步放什么调料.然后在做的过程中找每一步需要的调料.这就是很典型的面向过程的思维方式:怎么做,需要什

封装一个简单的原生js焦点轮播图插件

轮播图实现的效果为,鼠标移入左右箭头会出现,可以点击切换图片,下面的小圆点会跟随,可以循环播放.本篇文章的主要目的是分享封装插件的思路. 轮播图的我一开始是写成非插件形式实现的效果,后来才改成了封装成插件的形式. 首先要明白轮播图的实现原理和基本布局,大概就是外面有一个容器包裹着(通常是div),容器设置宽高,以及overflow为hidden,超出宽高部分隐藏, 容器里面又包含着另一个容器,包裹着所有的图片,宽为所有图片的总宽度,ul的position为absolute,通过改变ul的left