美文网首页SwiftOc & SwiftiOS知识
Swift编程(五):学做一个属于自己的View

Swift编程(五):学做一个属于自己的View

作者: zZ爱吃菜 | 来源:发表于2015-11-14 19:05 被阅读2039次

    写在前面:

    欢迎大家关注我的个人博客:<a href="http://blog.noasis.cn" >博客地址</a>,这里主要是我在个人开发时候遇到的坑和挖完的坑,包括 PHP CentOS 以及 Swift 等相关只是

    今天教给大家如何创建一个属于自己的View。(MVC设计模式有感)
    上次的总结对我影响很大,让我对IOS的MVC设计理解的更入更深了、也更清晰了。
    我觉得平时养成总结的习惯,应该算是一个程序员的自我修养了

    目标:

    • 学习如何做一个属于自己的公共View(ImageScroller)
    • 学习如何在视图类中创建代理,以及调用是使用代理
    • 学会像使用UITableView那样使用我们自己的View
    • 记录一点Swift下如何使用定时器 和 简单的小动画

    效果图

    scroller.gif

    具体步骤:

    每一个方法我都做了备注,以便大家理解

    1. 创建View:ImageScroller: UIView

    <pre>```swift
    class ImageScroller: UIView {

    weak var delegate: ImageScrollerDelegate?
    //属性参数
    var imageViewArray = Array<UIImage>()
    var scroller: UIScrollView!
    var pageControl:UIPageControl!
    //图片数
    private var imageCount:Int = 0
    //初始化
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.blueColor()
        self.frame = frame
    }
    
    //重载数据的方法
    func reload() {
        if let delegate = self.delegate {
            self.imageCount = delegate.numberOfImageViewsForImageScroller(self)
            initializeScrollView(self.imageCount)
            for var i = 0; i < self.imageCount; i++ {
                let imageView = delegate.imageScrollerAtIndex(self, index: i)
                imageView.frame = self.scroller.bounds
                var frame = imageView.frame
                frame.origin.x = CGFloat(i) * self.frame.size.width
                imageView.frame = frame
                self.scroller.addSubview(imageView)
            }
            initializePageControl()
            autoScroll()
        }
    }
    
    //组件一:UIScrollView的初始化
    func initializeScrollView(count: Int){
        self.scroller = UIScrollView()
        self.scroller.delegate = self
        self.scroller.contentSize = CGSizeMake(CGFloat(count) * self.frame.width,0)
        self.scroller.backgroundColor = UIColor.whiteColor()
        self.scroller.frame = self.bounds
        self.scroller.pagingEnabled = true
        self.scroller.bounces = false //反弹效果
        self.scroller.showsHorizontalScrollIndicator = false
        let tapRecognizer = UITapGestureRecognizer(target: self, action:Selector("scrollerTapped:"))
        self.scroller.addGestureRecognizer(tapRecognizer)
        self.addSubview(self.scroller)
    }
    
    //组件二:UIPageControl的初始化
    func initializePageControl(){
        // pageControl: 图片下面的圆点
        self.pageControl = UIPageControl()
        self.pageControl.center = CGPointMake(self.scroller.frame.width/2, self.scroller.frame.height-30)
        self.pageControl.currentPageIndicatorTintColor = UIColor.redColor()
        self.pageControl.pageIndicatorTintColor = UIColor.grayColor()
        self.pageControl.numberOfPages = self.imageCount
        self.addSubview(pageControl)
    }
    
    //自动滚动方法
    func autoScroll(){
        let timer = NSTimer(timeInterval: 4, target: self, selector: "scrolling", userInfo: nil, repeats: true)
        NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSDefaultRunLoopMode)
    }
    
    //滚动效果设计(这里设计的比较简单)
    func scrolling(){
        var index = Int(self.scroller.contentOffset.x / self.frame.size.width)
        if index >= self.imageCount - 1 {
            index = 0
            UIView.animateWithDuration(1) { () -> Void in
                self.scroller.contentOffset.x = 0
                self.pageControl.currentPage = index
            }
        }else{
            UIView.animateWithDuration(0.5) { () -> Void in
                self.scroller.contentOffset.x = self.frame.width * (CGFloat(index) + 1)
                self.pageControl.currentPage = index + 1
            }
        }
        
    }
    
    //点击事件
    func scrollerTapped(gesture: UITapGestureRecognizer) {
        if let delegate = self.delegate {
            let index = Int(self.scroller.contentOffset.x / self.frame.size.width)
            delegate.imageScrollerClickedAtIndex(self, index: index)
            self.pageControl.currentPage = index
        }
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    

    }

    //UIScrollView的拓展扩展:UIPageControl与图片联动
    extension ImageScroller: UIScrollViewDelegate {
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    let index = Int(self.scroller.contentOffset.x / self.frame.size.width)
    self.pageControl.currentPage = index
    }
    }

    
    ### 2.创建自己View的代理(Delegate)
    
    >把代理卸载 最上面。
    其实代理是个很方便的东西,我这里写了三个,我们知道UITableView有两种:Delegate(代理)和 DataSource(数据源),在上一节我说过DataSource是一种特殊的代理,其实他本质就是代理,只不过如果代理过多,需要帮代理分一下类,那么跟数据相关的例如:多少条数据,每条数据的cell等等都归类与名字叫DataSource下面了,就这么简单!
    
    <pre>```swift
    //属性代理
    @objc protocol ImageScrollerDelegate {
        //获取所有的图片数
        func numberOfImageViewsForImageScroller(scroller: ImageScroller) -> Int
        //获取每个UIImageView
        func imageScrollerAtIndex(scroller: ImageScroller, index: Int) -> UIImageView
        //每一个图片的点击事件
        func imageScrollerClickedAtIndex(scroller: ImageScroller, index: Int)
    }
    ```</pre>
    
    > 我们这里只有三个店里所以我就不需要明确分类了
    在上面的类中我已经没明确使用到了上面三个代理,不知道大家看代码的时候有没有发现,下面我一一介绍一下,每个代理的作用。
    ##注意:
    如果我在我的代理方法前面加一个 optional 那么就说明在使用我们的View时,此方法没有必要使用。我这里三个方法都是必须要被代理的,否则会报错
    
    ### 3.代理的使用
    
    >//这个必须写上,以便调用我们为View写好的代理
    weak var delegate: ImageScrollerDelegate? 
    
    <pre>```swift
    //重载数据的方法
        func reload() {
            if let delegate = self.delegate {
                self.imageCount = delegate.numberOfImageViewsForImageScroller(self)
                initializeScrollView(self.imageCount)
                for var i = 0; i < self.imageCount; i++ {
                    let imageView = delegate.imageScrollerAtIndex(self, index: i)
                    imageView.frame = self.scroller.bounds
                    var frame = imageView.frame
                    frame.origin.x = CGFloat(i) * self.frame.size.width
                    imageView.frame = frame
                    self.scroller.addSubview(imageView)
                }
                initializePageControl()
                autoScroll()
            }
        }
    ```</pre>
    
    > 我在重载数据是使用了次代理,使用方法很简单,只需要在我们需要他的使用,通过 <code>delegate.numberOfImageViewsForImageScroller(self)</code>的形式调用即可,(注意)代理是给那些实例我们View的Controller使用的,我们要相信他们会把我们需要的图片数imageCount通过<code>delegate.numberOfImageViewsForImageScroller(self)</code>传过来的,其实代理不过是个中间变量。
    总结:
    - 需求(一):图片数(Int)
    - 代理方法: 
      func numberOfImageViewsForImageScroller(scroller: ImageScroller) -> Int
    - 使用:
    self.imageCount = delegate.numberOfImageViewsForImageScroller(self)
    
    
    > - 需求(二):需要具体的图片(UIImageView)
    代理方法:
    func imageScrollerAtIndex(scroller: ImageScroller, index: Int) -> UIImageView
    使用:
    let imageView = delegate.imageScrollerAtIndex(self, index: i)
    
    
    >   - 需求(三):点击事件(Void)
     代理方法:
    func imageScrollerClickedAtIndex(scroller: ImageScroller, index: Int)
     使用:
    <pre>```swift
    //点击事件
        func scrollerTapped(gesture: UITapGestureRecognizer) {
            if let delegate = self.delegate {
                let index = Int(self.scroller.contentOffset.x / self.frame.size.width)
                delegate.imageScrollerClickedAtIndex(self, index: index)
                self.pageControl.currentPage = index
            }
        }
    ```</pre>
    
    ### 4.在Controller中使用ImageScroller
    
    > 1)实例并初始化ImageScroller
    
    <pre>```swift
        //尺寸
        imageScroller = ImageScroller(frame: CGRectMake(0, 0, self.view.frame.width, 300))
        imageScroller.delegate = self
        self.view.addSubview(imageScroller)
        imageScroller.reload()
    ```</pre>
    
    > 2)添加代理
    
    <pre>```swift
    extension MainViewController: ImageScrollerDelegate {
        
        func numberOfImageViewsForImageScroller(scroller: ImageScroller) -> Int {
            return 4 //测试阶段模拟数据
        }
        
        func imageScrollerAtIndex(scroller: ImageScroller, index: Int) -> UIImageView {
            let image = UIImage(named: "Welcome\\\\\\\\(1 + index).jpg")
            let imageView = UIImageView()
            imageView.image = image
            imageView.backgroundColor = UIColor.blackColor()
            //ScaleAspectFill:不影响图片的尺寸,只显示一部分
            //ScaleAspectFit:不影响图片的尺寸,按比例缩小全图显示
            //ScaleToFill:拉伸图片比例去适应全屏
            imageView.contentMode = .ScaleAspectFill
            return imageView
        }
        
        func imageScrollerClickedAtIndex(scroller: ImageScroller, index: Int) {
            print(index)
        }
    }
    ```</pre>
    
    ## 总结小知识:
    
     ###1. IOS定时器:
     >方法一
    
    <pre>```swift
    let timer = NSTimer(timeInterval: 4, target: self, selector: "scrolling", userInfo: nil, repeats: true)
    NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSDefaultRunLoopMode)
    ```</pre>
    
    ###2. 几种常用的contentMode方式
    
    <pre>```swift
    //ScaleAspectFill:不影响图片的尺寸,只显示一部分
    //ScaleAspectFit:不影响图片的尺寸,按比例缩小全图显示
    //ScaleToFill:拉伸图片比例去适应全屏
    imageView.contentMode = .ScaleAspectFill
    ```</pre>

    相关文章

      网友评论

      本文标题:Swift编程(五):学做一个属于自己的View

      本文链接:https://www.haomeiwen.com/subject/qlichttx.html