初识 swift 封装轮播图

一、简介

  换了一家公司、换了一个环境刚开始来公司自然不能有一丝一毫的放松,每天即使是没有什么工作也是看看这个博客、那个源码。尽量让自己更充实。慢慢的开始写几篇博客记录下自己遇到的一些问题和解决方法。其实也没什么就是瞎写没有什么思路反正就是遇到问题然后解决掉、最后分享出去。

  随着工作走向正规公司的项目不是那么赶、也就有时间尝试一些新的东西。只是不想刚开始编程哪会那么激进今天学这个明天学那个了。APPLE 发布 swift 有一年多了、不能说好也不能说不好、总之没有了解过时没有话语权的。所以就想试试。一开始我也想过仅使用swift 、后来发现这样做在我目前的项目中是不实际的因为有些东西已经用oc封装的很好了、总不能再花大把大把的时间重新来一次吧!最后决定使用oc+swift 混合编程。

  在做 app 开发过程中发现轮播图出现的概率是相当大的。 就先从这个入手吧!

  代码没有多的注释、但是简单易读。

二、用到的知识点

  构造函数、变量、属性封装、方法重载、

  构造函数:如果没有什么特殊的要求我们只要重写父类的构造函数就ok了、如果有特殊的业务需要自定义。

 1) func init(firstName:String,lastName:String)
 2) init(firstName:String,lastName:String)
以上两种方式 1)会报错 2)正确

变量、属性封装:这个一开始特别不适应、主要是 ? ! 这两个符号

如是代码:
 1)变量
private var _firstName:String=String(); //定义变量并初始化
private var _lastName:String?   //定义变量默认初始化
private var _sex:Bool=true;
private var _age:Int?;

 2) 属性
var firstName:String{
get{return _firstName}
set{_firstName=newValue}  // 默认setter 的传人参数名称是 newVlaue
}
var lastName:String{
get {return _lastName}
set(newLastName){_lastName=newLastName} // 可以定义setter 传入参数的名称 例如:newLastName
}

对于默认初始化 ‘?’ 的使用大家可以到网上搜索一下、这里讲一下如何使用定义成 ? 的变量或属性的使用。个人总结为:取值使用! 当访问其属性时用?

例如:
private _address:String?;
var Address:String?{
get {return _address!} // 这里使用 !
set {_address = newValue}
}

func test(){
self.Address?debugDescription // 访问该变量的相应属性使用?
var emtpy:String? = self.Address!// 取值调用!

self.Address = empty! //取值调用 !
}

? !的使用是相对的。

方法重载:直接看代码

    func loadData(image:Array<String>){
        self.loadData(image, title: nil);
    }
    func loadData(image:Array<String> ,title:Array<String>?){
    }

二、功能实现

  功能实现直接上代码 请导入 SDWebImage 第三方库

protocol KYScrollPageDelegate{

    func imageSelectTap(index:Int)

}

class KYScrollPage: UIView,UIScrollViewDelegate {

    private var noteTitle:UILabel?
    private var arrayTitle:Array<String>?
    private var arrayImage:Array<String>?
    private var mainScroll:UIScrollView?
    private var pageControl:UIPageControl?
    private var currentPage:Int=0;
    private var pageSize:Int=0;
    private var titleHeight:CGFloat=20.0;

    //MARK: ======================================================== 变量
    private var _startTimer:Bool = false;
    private var _timeInterval:Double=2.0;
    private var _hiddenTitle:Bool=false;
    private var _colorTitle:UIColor=UIColor.whiteColor();
    private var _hiddenPageControl:Bool=false;
    private var _contentHorizontalAlignment:UIControlContentHorizontalAlignment=UIControlContentHorizontalAlignment.Center

    var deleagte:KYScrollPageDelegate?

    override init(frame: CGRect) {
        super.init(frame: frame);
        self.mainScroll = UIScrollView();
        self.pageControl = UIPageControl();
        self.hiddenTitle = false;
        self.hiddenPageControl = false;
        self.contentHorizontalAlignment=UIControlContentHorizontalAlignment.Center;
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    //MARK: ======================================================== KYScrollPage 协议实现

    func loadData(image:Array<String>){
        self.loadData(image, title: nil);
    }
    func loadData(image:Array<String> ,title:Array<String>?){
        self.arrayImage = image;
        self.arrayTitle = title!;

        var tempArray:Array<String>=image;

        tempArray.insert(image.last!, atIndex: 0);
        tempArray.append(image.first!);

        self.arrayImage = tempArray;
        self.pageSize = self.arrayImage!.count;

        self.mainScroll!.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
        var width:CGFloat = self.frame.size.width * CGFloat(self.pageSize);
        self.mainScroll?.contentSize=CGSizeMake(width, self.frame.size.height);
        self.mainScroll?.showsHorizontalScrollIndicator = false;
        self.mainScroll?.showsVerticalScrollIndicator = false;
        self.mainScroll?.scrollsToTop = false;
        self.mainScroll?.pagingEnabled = true;
        self.mainScroll?.delegate = self;

        for (var i:Int=0; i<self.pageSize; i++) {

            let imageUrl:String = self.arrayImage![i];

            var imgeView:UIImageView = UIImageView();
            if imageUrl.hasPrefix("http://")  {
                imgeView.sd_setImageWithURL(NSURL(string: imageUrl), placeholderImage: UIImage(named:"Icon-60"));
            } else
            {
                imgeView.image=UIImage(named:"Icon-60");
            }

            imgeView.frame = CGRectMake(self.frame.size.width*CGFloat(i), CGFloat(0), self.frame.size.width, self.frame.size.height);

            imgeView.tag = i;
            var Tap:UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("imageGestureTap:"));
            Tap.numberOfTapsRequired=1;
            Tap.numberOfTouchesRequired=1;

            imgeView.userInteractionEnabled=true;
            imgeView.addGestureRecognizer(Tap);
            self.mainScroll?.addSubview(imgeView);

        }

        self.mainScroll?.setContentOffset(CGPointMake(self.frame.size.width, 0), animated: false);
        self.addSubview(self.mainScroll!);
        self.contentHorizontalAlignment = _contentHorizontalAlignment;
        self.pageControl!.currentPage=0;
        self.pageControl!.pageIndicatorTintColor = UIColor(red: 155/255.0, green:  155/255.0, blue:  155/255.0, alpha: 1.0);
        self.pageControl!.currentPageIndicatorTintColor=UIColor.whiteColor();
        self.pageControl!.userInteractionEnabled = false;
        self.pageControl!.numberOfPages=self.pageSize-2;
        self.pageControl?.hidden=self.hiddenPageControl;
        self.addSubview(self.pageControl!);

        if arrayTitle != nil{
            self.noteTitle = UILabel(frame:CGRectMake(10,self.frame.size.height-self.titleHeight, self.frame.size.width, self.titleHeight));
            self.noteTitle!.text=self.arrayTitle!.first;
            noteTitle?.textColor = _colorTitle;
            noteTitle?.backgroundColor=UIColor.clearColor();
            noteTitle?.font=UIFont.systemFontOfSize(13.0);
            noteTitle?.hidden=self.hiddenTitle;
            self.addSubview(noteTitle!);
        }
    }

    //MARK: - ========================================================= UIScrollView 协议实现
    func scrollViewDidScroll(scrollView: UIScrollView) {
        var pageWidth:CGFloat = scrollView.frame.size.width;
        var x:CGFloat = scrollView.contentOffset.x;
        var page:Int = Int(((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1);
        self.currentPage=page;

        pageControl!.currentPage=page-1;
        var titleIndex:Int=page-1;

        if (titleIndex==self.arrayTitle!.count) {
            titleIndex=0;
        }
        if (titleIndex<0) {
            titleIndex=self.arrayTitle!.count-1;
        }
        if (titleIndex>self.arrayTitle!.count-1) {
            noteTitle?.text="";
        }
        else
        {
            noteTitle?.text=self.arrayTitle![titleIndex];
        }
    }

    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        if (currentPage==0) {
            scrollView.setContentOffset(CGPointMake(CGFloat(arrayImage!.count-2)*self.frame.size.width, CGFloat(0)), animated: false)
        }
        if (currentPage==(self.arrayImage!.count-1)) {
            scrollView.setContentOffset(CGPointMake(self.frame.size.width, CGFloat(0)), animated: false)
        }
    }

    @objc private func imageGestureTap(getsture:UITapGestureRecognizer){
        if (self.deleagte != nil) {
            self.deleagte?.imageSelectTap(getsture.view!.tag);
        }
    }

    // pagecontrol 选择器的方法
    func turnPage()
    {
        var page:Int = self.pageControl!.currentPage;
        self.mainScroll?.scrollRectToVisible(CGRectMake(CGFloat(self.frame.size.width*CGFloat(page+1)),0,self.frame.size.width,self.frame.size.height), animated: false);

    }
    // 定时器 绑定的方法
    func runTimePage()
    {
        var page:Int = self.pageControl!.currentPage; // 获取当前的page
        page++;
        page = page >= self.arrayImage!.count-2 ? 0 : page ;
        self.pageControl!.currentPage = page;
        self.turnPage();
    }
    //MARK: ======================================================== 属性封装
    /// 图片标题是否显示
    var hiddenTitle:Bool {
        get{ return _hiddenTitle;}
        set{
            _hiddenTitle = newValue;
            if noteTitle != nil {
                self.noteTitle?.hidden=_hiddenTitle;
            }
        }
    }
    /// 图片标题颜色
    var colorTitle:UIColor{
        get{ return _colorTitle}
        set{
            _colorTitle = newValue;
            if noteTitle != nil {
                self.noteTitle?.textColor=_colorTitle;
            }
        }
    }
    /// 是否显示 UIPageControl
    var hiddenPageControl:Bool{
        get{return _hiddenPageControl}
        set{
            _hiddenPageControl = newValue;
            if pageControl != nil {
                self.pageControl?.hidden=_hiddenPageControl;
            }
        }
    }
    /// UIPagerControl 显示位置
    var contentHorizontalAlignment:UIControlContentHorizontalAlignment{
        get{ return _contentHorizontalAlignment }
        set{
            _contentHorizontalAlignment = newValue;
            let size:CGSize =   self.pageControl!.sizeForNumberOfPages(pageSize)
            switch _contentHorizontalAlignment {
            case   UIControlContentHorizontalAlignment.Center :
                self.pageControl?.center=CGPointMake(self.center.x, self.frame.size.height-self.titleHeight+self.titleHeight/2)
                break;
            case UIControlContentHorizontalAlignment.Left :
                self.pageControl?.frame.origin.x=size.width/2;
                break;
            case UIControlContentHorizontalAlignment.Right :
                self.pageControl?.frame.origin.x=self.frame.size.width-size.width/2
                break;
            default:
                break;
            }
        }
    }
    /// 计时器
    var startTimer:Bool{
        get{ return _startTimer}
        set{
            _startTimer = newValue;
            if _startTimer {
                NSTimer.scheduledTimerWithTimeInterval(_timeInterval, target: self, selector: Selector("runTimePage"), userInfo: nil, repeats: true);
            }
        }
    }

}

调用代码:

var headerView:KYScrollPage? = KYScrollPage(frame: CGRectMake(0, 0, self.view.frame.size.width, 150));
       headerView?.contentHorizontalAlignment=UIControlContentHorizontalAlignment.Right;
        headerView?.hiddenTitle=false;
        headerView?.startTimer=true;
        headerView!.loadData(["http://img0.bdstatic.com/img/image/b4ff47b072b4b8934864f4be92ee07c01409737708.jpg","http://f.hiphotos.baidu.com/image/w%3D230/sign=17e661b9eb50352ab161220b6343fb1a/8435e5dde71190ef5bd3fcd1cc1b9d16fdfa6097.jpg","http://f.hiphotos.baidu.com/image/w%3D230/sign=17e661b9eb50352ab161220b6343fb1a/8435e5dde71190ef5bd3fcd1cc1b9d16fdfa6097.jpg","http://f.hiphotos.baidu.com/image/w%3D230/sign=17e661b9eb50352ab161220b6343fb1a/8435e5dde71190ef5bd3fcd1cc1b9d16fdfa6097.jpg","http://f.hiphotos.baidu.com/image/w%3D230/sign=17e661b9eb50352ab161220b6343fb1a/8435e5dde71190ef5bd3fcd1cc1b9d16fdfa6097.jpg","http://f.hiphotos.baidu.com/image/w%3D230/sign=17e661b9eb50352ab161220b6343fb1a/8435e5dde71190ef5bd3fcd1cc1b9d16fdfa6097.jpg","http://f.hiphotos.baidu.com/image/w%3D230/sign=17e661b9eb50352ab161220b6343fb1a/8435e5dde71190ef5bd3fcd1cc1b9d16fdfa6097.jpg"], title: ["成龙1","成龙2","成龙2","成龙2","成龙2","成龙2","成龙2"]);

        headerView?.deleagte=self;

        self.tableView.tableHeaderView=headerView;

三、问题总结

开始做的时候确实遇到了几个问题

1、 属性封装的问题

  由于oc 用习惯了总以为 每个属性都有一个默认的字段 _属性 所以在 get{return ...} 花费了些时间

set{_属性=....} 不晓得默认的字段名称花费了些时间

swift 的属性应该是和java 很像。对应定义一个私有成员变量。

2、类型不匹配的问题

  由于不明白 ? ! 怎么使用 总是会遇到类型转换不匹配

等号右边的报错通常需要对不一致的类型进行强转 、对于?标示的要 使用 ! 取值。

3、初始值的问题

变量、属性 声明后没有赋值或者标示为 ? 在构造函数总是报错。swift 变量、属性必须初始化。

时间: 2024-10-09 20:25:03

初识 swift 封装轮播图的相关文章

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

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

用原生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

IOS 封装轮播图

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

原生js封装轮播图

个人实际开发中用到的效果问题总结出来便于自己以后开发查看调用,如果也适用其他人请随意拿走勿喷就行! 原生js对于思路要求比较高,在js代码我都写有备注,足够理解并使用,即使是小白或者刚入行的程序员也比叫好理解,其轮播图只是一个简单的效果,缺点没有写动画效果看起来比较生硬,优点简单好学,容易理解,非常实用 轮播图介绍 : 三张图片,图片下方有对应图片数量的三个指示点,左右有切换指示,左右指示可要可不要 HTML代码 <div id="mlBox"> <div id=&q

封装轮播图

创建一对继承于UIView的类,在.h文件中添加属性.初始化方法, // 数组@property (nonatomic, strong) NSMutableArray *imgNameArray;// 初始化方法- (instancetype)initWithFrame:(CGRect)frame interVal:(NSTimeInterval)interval; 在.m的文件中添加相应的属性 // scrollView@property (nonatomic, strong) UIScrol

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

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

js-BOM之offset家族、移动函数的封装升级(轮播图)

Obj.style.width/obj.style.height与obj.offsetWidth/obj.offsetHeight的区别: <style> #div1{ height: 200px; background-color: red; } #div2{ width: 200px; height: 200px; background-color: green; } </style> </head> <body> <div style="

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

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

通过轮播图例子复习封装动画函数和定时器

概述:使用js实现自动播放.无缝连接的轮播图 图片轮播的实质是改变图片相对于父对象的左边距的值,利用offsetLeft获取,利用style.left修改 封装动画函数如下: function animate(element,target) { clearInterval(element.timeId); element.timeId=setInterval(function(){ var current=element.offsetLeft; var step=10; step=target>