美文网首页
自定义tableView加载更多控件

自定义tableView加载更多控件

作者: 氮化镓加砷 | 来源:发表于2016-05-07 13:02 被阅读352次

前几天做了一个自定义下拉刷新的控件,http://www.jianshu.com/p/db2a46264522

现在想做一个在自定义上拉加载更多的控件,上拉加载的控件要比下拉刷新的简单的多,因为加载控件不应该有过多的动画,因为用户需要流畅的体验感,你懂的。所以状态就少了很多

首先依然是将我们的加载控件动态绑定到SCrollView中

 private var pullUpLoadMoreView: QPullUpLoadMoreView? {
        get {
            return objc_getAssociatedObject(self, &Q_associatedKeys.pullUpLoadMoreView ) as? QPullUpLoadMoreView
        }
        set {
            objc_setAssociatedObject(self, &Q_associatedKeys.pullUpLoadMoreView, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

控件的状态

public
enum pullUpLoadMoreState: Int {
    case Default
    case Dragging
    case Trigger
    case Failure
}

依然需要监听SCROLLView的状态,但是在这里只需要监听2个就够了

var observing: Bool = false {
        didSet {
            guard let scrollView = self.scrollView else { return }
            if observing {
                scrollView.safe_addObserver(self, forKeyPath: QTableViewRefreshConfig.KeyPaths.ContentOffset)
                scrollView.safe_addObserver(self, forKeyPath: QTableViewRefreshConfig.KeyPaths.contentSize)
            } else {
                scrollView.safe_removeObserver(self, forKeyPath: QTableViewRefreshConfig.KeyPaths.ContentOffset)
                scrollView.safe_removeObserver(self, forKeyPath: QTableViewRefreshConfig.KeyPaths.contentSize)
            }
        }
    }


加载控件比下拉刷新控件更加方便的是,上拉加载的ContentInsetBottom的值可以是固定的,你可以想象一下,为什么可以是固定的,因为为了流畅度,当scrollViewOffsetY达到最底端的时候,我们控件就应该是触发态了,

    override func didMoveToSuperview() {
        super.didMoveToSuperview()
        var contentInset = self.scrollView!.contentInset
        contentInset.bottom =  QTableViewRefreshConfig.LoadingMoreOffset
        self.scrollView!.contentInset = contentInset
    }

在做一个提示的label

 init(){
        super.init(frame: CGRectZero)
        
        self.labelMsg.frame = CGRectMake(0, 0, 0, 0)
        self.labelMsg.text = "loading ... "
        self.labelMsg.font = UIFont(name: "ljq", size: 10.0)
        self.labelMsg.textAlignment = NSTextAlignment.Center
        self.addSubview(self.labelMsg)
        
        
    }

监听

override  func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        if keyPath == QTableViewRefreshConfig.KeyPaths.ContentOffset {
            if let scrollView = self.scrollView  where scrollView.contentOffset.y + scrollView.frame.size.height > scrollView.contentSize.height  {
                if scrollView.contentOffset.y != 0 {
                    if self.state == .Default{
                        self.state = .Trigger
                        self.labelMsg.text = "loading ... "
                    }else if state == .Trigger{
                        
                    }
                }
            }
        }else if keyPath == QTableViewRefreshConfig.KeyPaths.contentSize{
            if let scrollView = self.scrollView where scrollView.contentSize.height != 0 {
                 self.frame = CGRectMake(0, self.scrollView!.contentSize.height, self.scrollView!.contentSize.width, QTableViewRefreshConfig.LoadingMoreOffset)
                 self.labelMsg.frame = CGRectMake(0, QTableViewRefreshConfig.LoadingMoreOffset/4, self.scrollView!.contentSize.width, QTableViewRefreshConfig.LoadingMoreOffset/2)
                self.state = .Default
            }
        }
    }

整个流程就是当滑动到底部的时候 state就变成Trigger, 然后开始加载更多,当加载完毕的时候COntentSize会重新计算,我们在监听COntentSize变化来调整我们LoadingMoreView的位置,使它一直保持在scrollView的底部。

当然为了效果好一点,我们需要一些小小的调整,比如在调用insertRowsAtIndexPaths方法之前,将LoadingMoreView隐藏掉,不然可能会出现重影的效果。

 var state:pullUpLoadMoreState = .Default{
        didSet{
            switch state {
            case .Default: self.hidden = false;
            case .Dragging: break;
            case .Trigger: self.actionHandler!()
            case .Failure: self.labelMsg.text = "load fail , please up again"  ; self.state = .Default
            }
        }
    }

在控制器里面调用

        
        self.tableView!.Q_addPullUpLoadMoreWithActionHandler{
            [unowned self] () -> Void in
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2 * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
                
                self.requreMoreData() //数据获取
               // self.tableView!.Q_failLoadMore()
                self.tableView!.Q_completeLoadMore()
                var cells:[NSIndexPath] = [NSIndexPath]()
                for  index in 0...9 {
                    let cell:NSIndexPath = NSIndexPath(forRow: index+self.cellNum, inSection: 0)
                    cells.append(cell)
                }
                self.cellNum += 10
                self.tableView!.insertRowsAtIndexPaths(cells, withRowAnimation: UITableViewRowAnimation.Automatic)
            })
        }

当然如果向在View里面做点动画也是很轻易的事情。附上效果图

2016-05-07 13_01_59.gif

git地址 https://github.com/lvjiaqijiaqi/tableViewRefresh

相关文章

网友评论

      本文标题:自定义tableView加载更多控件

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