天天看點

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);
        }      

無善無惡心之體,

有善有惡意之動,

知善知惡是良知,

為善去惡是格物。