31.怎样添加自定义视图?

  自定义视图是在项目开发中经常会面临的工作,通过对视图进行封装,能达到更好的复用性,并使得VC里面的逻辑更加清晰。本篇将对实际项目中常用的图片轮播进行封装。

1.先从源码看起

  首先,定义了一个枚举类型,用于区分图片的存储类型:网络图片还是本地图片。

/**
 图片存储类型

 - Local:   本地图片
 - Network: 网络图片
 */
enum GofImageStoreType: Int
{
    case Local = 0;
    case Network;
}

  然后对图片轮播类进行了功能封装。

class GofImageScrollView: UIView
{
    /// 图片数组
    private var arrImage: [String]?;
    /// 分页
    private var imgPageControl: UIPageControl?;
    /// 按钮单击回调Block
    private var btnClick: GofBtnClickBlock?;
    /// 滚动视图
    private var imgScrollView: UIScrollView?;
    /// 计时器
    private var timer: NSTimer?;
    /// 当前页索引
    private var iCurrentIndex: NSInteger?;

    /**
     创建GofImageScrollView

     - parameter array:         图片数组(本地图片传图片名称数组,网络图片传图片URL数组,均为字符串数组)
     - parameter storeType:     图片存储类型(网络图片/本地图片)
     - parameter btnClickBlock: 按钮单击处理
     - parameter superView:     父视图
     - parameter constraints:   约束

     - returns: GofImageScrollView
     */
    static func gof_ImageScrollView(array: [String], storeType: GofImageStoreType, btnClickBlock: GofBtnClickBlock?, superView: UIView?, constraints: GofConstraintMaker?) -> GofImageScrollView
    {
        let scroll = GofImageScrollView();

        if superView != nil
        {
            superView!.addSubview(scroll);

            if constraints != nil
            {
                scroll.snp_makeConstraints(closure: { (make) in
                    constraints!(make);
                })

                scroll.showScrollViewWithImageArray(array, storeType: storeType, btnClickBlock: btnClickBlock);
            }
        }

        return scroll;
    }

    /**
     显示图片轮播

     - parameter array:         图片数组(本地图片传图片名称数组,网络图片传图片URL数组,均为字符串数组)
     - parameter storeType:     图片存储类型(网络图片/本地图片)
     - parameter btnClickBlock: 按钮单击处理
     */
    func showScrollViewWithImageArray(array: [String], storeType: GofImageStoreType, btnClickBlock: GofBtnClickBlock?)
    {
        //变量赋值
        arrImage = array;
        btnClick = btnClickBlock;
        iCurrentIndex = 1;

        //滚动视图
        imgScrollView = UIScrollView.init();
        imgScrollView!.delegate = self
        imgScrollView!.pagingEnabled = true;
        imgScrollView!.contentSize = CGSizeMake(self.bounds.size.width * CGFloat(array.count + 2), 0);
        imgScrollView!.contentOffset = CGPointMake(self.bounds.size.width * 2, 0);
        imgScrollView!.showsHorizontalScrollIndicator = false;
        imgScrollView!.showsVerticalScrollIndicator = false;
        self.addSubview(imgScrollView!);
        imgScrollView?.snp_makeConstraints(closure: { (make) in
            make.edges.equalTo(self);
        });

        //内容容器视图
        let containerView = UIView();
        imgScrollView?.addSubview(containerView);
        containerView.snp_makeConstraints { (make) in
            make.edges.equalTo(self.imgScrollView!);
            make.top.equalTo(0);
            make.height.equalTo(self);
        }

        //分页小圆点
        imgPageControl = UIPageControl.init();
        imgPageControl?.numberOfPages = array.count;
        imgPageControl?.currentPage = 0;
        imgPageControl?.userInteractionEnabled = false;
        imgPageControl?.currentPageIndicatorTintColor = UIColor.greenColor();
        imgPageControl?.pageIndicatorTintColor = UIColor.grayColor();
        self.addSubview(imgPageControl!);
        imgPageControl?.snp_makeConstraints(closure: { (make) in
            make.left.equalTo(0);
            make.top.equalTo(self.snp_bottom).offset(-20);
            make.right.equalTo(0);
            make.height.equalTo(20);
        })

        //添加图片
        for i in 0...array.count - 1
        {
            //图片
            let button = UIButton.gof_buttonWithTitle(nil, superView: containerView, constraints: { (make) in
                    make.leading.equalTo(kScreenWidth * CGFloat(i + 1));
                    make.top.equalTo(0);
                    make.width.equalTo(kScreenWidth);
                    make.bottom.equalTo(0);
                }, touchup: { [unowned self] (btn) in
                    if (self.btnClick != nil)
                    {
                        self.btnClick(btn);
                    }
            });
            button.tag = 100 + i;
            if .Local == storeType
            {
                button.setImage(gof_ImageWithName(array[i > (array.count - 1) ? 0 : i] ), forState: .Normal);
            }
            else
            {
                button.kf_setImageWithURL(NSURL(string: array[i > (array.count - 1) ? 0 : i] ), forState: .Normal);
            }
        }

        //右边加个图片用于过渡
        let rightButton = UIButton.gof_buttonWithTitle(nil, superView: containerView, constraints: { (make) in
                make.leading.equalTo(kScreenWidth * CGFloat(array.count + 1));
                make.top.equalTo(0);
                make.width.equalTo(kScreenWidth);
                make.bottom.equalTo(0);
            }, touchup: { [unowned self] (btn) in
                if (self.btnClick != nil)
                {
                    self.btnClick(btn);
                }
            });
        rightButton.tag = 100;

        //左边加个图片用于过渡
        let leftButton = UIButton.gof_buttonWithTitle(nil, superView: containerView, constraints: { (make) in
                make.leading.equalTo(0);
                make.top.equalTo(0);
                make.width.equalTo(kScreenWidth);
                make.bottom.equalTo(0);
            }, touchup: { [unowned self] (btn) in
                if (self.btnClick != nil)
                {
                    self.btnClick(btn);
                }
            });
        leftButton.tag = 100 + array.count - 1;

        containerView.snp_makeConstraints { (make) in
            make.right.equalTo(rightButton);
        }

        if .Local == storeType
        {
            rightButton.setImage(gof_ImageWithName(array[0]), forState: .Normal);
            leftButton.setImage(gof_ImageWithName(array[array.count - 1]), forState: .Normal);
        }
        else
        {
            rightButton.kf_setImageWithURL(NSURL(string: array[0]), forState: .Normal);
            leftButton.kf_setImageWithURL(NSURL(string: array[array.count - 1]), forState: .Normal);
        }

        self.startScrollForInit();
    }

    /**
     初始化操作
     */
    func startScrollForInit()
    {
        NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: #selector(startScroll), userInfo: nil, repeats: true);
    }

    /**
     设置初始滚动位置并开启定时任务
     */
    func startScroll()
    {
        self.scrollToInit();

        //启动定时器
        self.startTime();
    }

    /**
     按钮点击

     - parameter btn: 按钮
     */
    func btnClick(btn:UIButton) -> Void
    {
        if (btnClick != nil)
        {
            btnClick!(btn);
        }
    }

    /**
     开启计时器
     */
    func startTime() -> Void
    {

        if timer == nil
        {
            timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: #selector(scrollForTime), userInfo: nil, repeats: true);
        }
    }

    /**
     添加滚动
     */
    func scrollForTime() -> Void
    {
        iCurrentIndex = iCurrentIndex! + 1;
        if iCurrentIndex == arrImage!.count + 1
        {
            imgScrollView!.setContentOffset(CGPointMake(self.bounds.size.width * CGFloat(iCurrentIndex!), 0), animated:true);
            iCurrentIndex = 1;
            self.performSelector(#selector(scrollToInit), withObject: nil, afterDelay: 0.5);
        }
        else
        {
            imgScrollView!.setContentOffset(CGPointMake(self.bounds.size.width * CGFloat(iCurrentIndex!), 0), animated:true);
        }
        imgPageControl!.currentPage = iCurrentIndex! - 1;
    }

    /**
     回到原点
     */
    func scrollToInit() -> Void
    {
        imgScrollView!.setContentOffset(CGPointMake(self.bounds.size.width * CGFloat(iCurrentIndex!), 0), animated:false);
    }
}

  最后,通过扩展来遵守UIScrollViewDelegate协议。

extension GofImageScrollView: UIScrollViewDelegate
{
    func scrollViewWillBeginDragging(scrollView: UIScrollView)
    {
        if timer != nil
        {
            timer!.invalidate();
            timer = nil;
        }
    }

    func scrollViewDidEndDecelerating(scrollView: UIScrollView)
    {
        let index: NSInteger = NSInteger(scrollView.contentOffset.x / kScreenWidth);

        if index == (arrImage!.count + 1)
        {
            scrollView.contentOffset = CGPointMake(self.bounds.size.width, 0);
            imgPageControl!.currentPage = 0;
            iCurrentIndex = 1;
        }
        else if index == 0
        {
            scrollView.contentOffset = CGPointMake(CGFloat(arrImage!.count) * self.bounds.size.width, 0);
            imgPageControl!.currentPage = arrImage!.count - 1;
            iCurrentIndex = arrImage!.count;
        }
        else
        {
            imgPageControl!.currentPage = index - 1;
            iCurrentIndex = index;
        }
        self.startTime();
    }
}

2.怎么用?

        //定义图片数组
        let imageArray: [String] = ["http://tupian.enterdesk.com/2012/1025/gha/1/ebterdesk%20%2810%29.jpg", "http://d.3987.com/qingzang_140909/007.jpg", "http://d.3987.com/mrzr_131022/007.jpg"];
        //声明图片轮播视图
        let scroll = GofImageScrollView.gof_ImageScrollView(imageArray, storeType: .Network, btnClickBlock: { (btn) in
             printLog("Tag:\(btn.tag)");
            }, superView: self.view) { (make) in
                make.top.equalTo(0);
                make.left.right.equalTo(0);
                make.height.equalTo(200);
        }
时间: 2024-11-08 21:23:24

31.怎样添加自定义视图?的相关文章

使用WindowManager添加自定义视图

原文地址:使用WindowManager添加自定义视图 在写手机卫士的时候,用户拨打|接听电话需要显示号码归属地,然后出现了一些异常,在此留下记号,希望对麻友们有帮助: BUG教程 在使用 view = View.inflate(this, R.layout.ui_toast, null);获得View对象后wm.addView出现错误: 10-12 14:29:06.166: E/AndroidRuntime(1268): Caused by: android.view.WindowManag

jquery easyui datagrid detailview groupview添加自定义视图view

var myview = $.extend({}, $.fn.datagrid.defaults.view, { onAfterRender: function (target) { $.fn.datagrid.defaults.view.onAfterRender.call(this, target); refreshView(target); }, insertRow: function (target, index, row) { $.fn.datagrid.defaults.view.i

iOS 视图控制器转场详解

前言的前言 唐巧前辈在微信公众号「iOSDevTips」以及其博客上推送了我的文章后,我的 Github 各项指标有了大幅度的增长,多谢唐巧前辈的推荐.有些人问我相关的问题,好吧,目前为止就几个,由于没有评论系统,实在不方便交流,但我也没把博客好好整理,一直都在简书上写博客,大家有问题请移步我的简书本文章的页面.关于交流,我想说这么几点: 1.问问题就好,不要加上大神大牛之类的称呼,与本文有关的问题我尽量回答:不负责解析转场动画,看心情回答. 2.去我的简书下留言是最有效的交流方式,要加我好友就

[Swift通天遁地]一、超级工具-(10)使用地图视图MKMapView的相机功能实现创建三维地图

本文将演示使用地图视图MKMapView的相机功能实现创建三维地图. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] 1 import UIKit 2 //在当前的类文件中引入所需的类库 3 import MapKit 4 5 class ViewController: UIViewController { 6 7 override func viewDidLoad() { 8 super.viewDidLoad() 9 // Do any additiona

[Swift通天遁地]五、高级扩展-(8)ImageView(图像视图)的各种扩展方法

本文将演示图像和图像视图在下载.压缩.裁剪方面的扩展. 首先确保在项目中已经安装了所需的第三方库. 点击[Podfile],查看安装配置文件. 1 platform :ios, '12.0' 2 use_frameworks! 3 4 target 'DemoApp' do 5 source 'https://github.com/CocoaPods/Specs.git' 6 pod 'EZSwiftExtensions' 7 end 根据配置文件中的相关配置,安装第三方库. 然后点击打开[De

SpringMVC源码阅读:视图解析器

1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring4.3.7)分析,弄清楚SpringMVC如何完成视图解析的 2.源码分析 在SpringMVC源码阅读:拦截器分析过doDispatch的运行过程,这里再分析一遍 回到DispatcherServlet类的doDispatch方法,看看doDispatch如何获取ModelAndView Hand

[转]NopCommerce之旅: 应用启动

本文转自:http://www.cnblogs.com/devilsky/p/5359881.html 我的NopCommerce之旅(6): 应用启动 一.基础介绍 Global.asax 文件(也称为 ASP.NET 应用程序文件)是一个可选文件,该文件包含响应 ASP.NET 或 HTTP 模块所引发的应用程序级别和会话级别事件的代码. Application_Start是其中一个事件,在HttpApplication 类的第一个实例被创建时,该事件被触发它允许你创建可以由所有HttpAp

[转]Material Design Library 23.1.0的新变化与代码实战

Design Library出来已经快有一个月了,当时大概看了一下介绍这个新版本变化的译文,内容不多,给我印象最深的就是Percent lib.AppBarLayout 和NavigationView的变化,当然还有Design Lib的一些控件内部实现的变化没有介绍,从而使得在使用新版本的控件时候难免因为版本的不同会发生一些异常,而本人正好在上个星期对一个项目换库时发现了这个问题,什么问题呢? NavigationView使用注意的问题 就是NavigationView的内部实现发生了改变,它

iOS开发——UI篇Swift篇&UIScrollView

UIScrollView 1 //返回按钮事件 2 @IBAction func backButtonClick() 3 { 4 self.navigationController?.popViewControllerAnimated(true) 5 } 6 7 //创建滚动视图 8 var mainScrollView:UIScrollView! 9 10 var view1:UIView! 11 var view2:UIView! 12 var view3:UIView! 13 14 //创