如何使用集合视图的滚动和边框元素位置从所有方面触发分页?

时间:2017-11-22 11:06:03

标签: ios swift uicollectionview

我已经创建了自定义集合视图布局(用于多向滚动),运行成功。现在,我试图从各个方面(顶部,左侧,右侧和底部)实现分页。为此,我正在跟踪滚动方向,并在到达边界元素时,我希望在该方向上分页(加载更多数据)。但由于我需要将页面默认设置为左上角位置,因此已经到达左上角的元素,从而导致冲突。你能帮忙吗?

我试过以下代码:

import UIKit

class ViewController: UIViewController{

    var cellId: String = "MyCellId"
    var vPivotPrev = 0
    var vPivotNext = 19
    var hPivotPrev = 0
    var hPivotNext = 29
    var targetPoint = CGPoint(x: 0, y: 0)
    var scrollDirection: String = ""
    var scrolledDailyToTop:String = ""
    var scrolledDailyToBottom:String = ""
    var scrolledDailyToLeft:String = ""
    var scrolledDailyToRight:String = ""
    var shouldPaginate:Bool = false


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        showCollectionView()
    }

    var customCollectionView: UICollectionView = {                                //  CODE TO CREATE CUSTOM COLLECTION VIEW

        let layout = CustomCollectionViewLayout()

        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)

        return cv
    }()

    class CustomCell: UICollectionViewCell{                                             //  CODE TO CREATE CUSTOM CELLS

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

        override init(frame: CGRect) {
            super.init(frame: frame)
            setup()
        }

        let label: UILabel = {
            let myLabel = UILabel()
            return myLabel
        }()

        func setup(){
            addSubview(label)

        }
    }

    func showCollectionView(){
        view.addSubview(customCollectionView)
        customCollectionView.backgroundColor = .darkGray
        customCollectionView.frame = CGRect(x: 60, y: 145, width: UIScreen.main.bounds.size.width-120, height: UIScreen.main.bounds.size.height/1.8)

        customCollectionView.dataSource = self
        customCollectionView.delegate  = self
        customCollectionView.register(CustomCell.self, forCellWithReuseIdentifier: cellId)       //  REGISTER CELL CLASS
    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        //  DETECT SCROLL DIRECTION CODE
        var currentPoint = scrollView.contentOffset

        if(targetPoint.y > currentPoint.y){
            scrollDirection = "going up"
            print(scrollDirection)
        }
        else if(targetPoint.y < currentPoint.y){
            scrollDirection = "going down"
            print(scrollDirection)
        }

        if(targetPoint.x > currentPoint.x){
            scrollDirection = "going left"
            print(scrollDirection)
        }
        else if(targetPoint.x < currentPoint.x){
            scrollDirection = "going right"
            print(scrollDirection)
        }

        self.targetPoint = scrollView.contentOffset
    }

}


extension ViewController: UICollectionViewDataSource{

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 20
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 30
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CustomCell
        cell.label.text = "\(indexPath.section.description),\(indexPath.item.description)"
        cell.backgroundColor = .lightGray
        cell.label.frame = CGRect(x: 0, y: 0, width: cell.contentView.bounds.width, height: 10)
        cell.label.textColor = .white
        cell.bringSubview(toFront: cell.label)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        for visibleIndices in collectionView.indexPathsForVisibleItems{

            if(visibleIndices.section == vPivotPrev){
                scrolledDailyToTop = "top"
                shouldPaginate = true
                paginate()
            }
            else if(visibleIndices.section == vPivotNext){
                scrolledDailyToBottom = "bottom"
                shouldPaginate = true
                paginate()
            }
            else if(visibleIndices.item == hPivotPrev){
                scrolledDailyToLeft = "left"
                shouldPaginate = true
                paginate()
            }
            else if(visibleIndices.item == hPivotNext){
                scrolledDailyToRight = "right"
                shouldPaginate = true
                paginate()
            }
        }
    }

    func paginate(){
        print("Swipe Direction: \(scrollDirection)")
        if(shouldPaginate == true){
            if(self.scrollDirection == "going down" && self.scrolledDailyToTop == "top"){ //  PAGINATING USING 9 BOX LOGIC

                    print("Fetch Vertical previous page")
                    //getNewPageData(gotopageURL: self.goToPageURL)
                    self.customCollectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .bottom, animated: false)
                    self.customCollectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .left, animated: false)
                    shouldPaginate = false

            }
            else if(self.scrollDirection == "going up" && self.scrolledDailyToBottom == "bottom"){
                print("Fetch Vertical next page")
                //getNewPageData(gotopageURL: self.goToPageURL)
                self.customCollectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .top, animated: false)
                self.customCollectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .left, animated: false)
                shouldPaginate = false
            }
            else if(self.scrollDirection == "going right" && self.scrolledDailyToLeft == "left"){
                print("Fetch Horizontal previous page")
                //getNewPageData(gotopageURL: self.goToPageURL)
                self.customCollectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .top, animated: false)
                self.customCollectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .right, animated: false)
                shouldPaginate = false
            }
            else if(self.scrollDirection == "going left" && self.scrolledDailyToRight == "right"){
                print("Fetch Horizontal next page")
                //getNewPageData(gotopageURL: self.goToPageURL)
                self.customCollectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .top, animated: false)
                self.customCollectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .left, animated: false)
                shouldPaginate = false
            }

            scrolledDailyToTop = ""
            scrolledDailyToBottom = ""
            scrolledDailyToLeft = ""
            scrolledDailyToRight = ""
        }
    }

}

extension ViewController: UICollectionViewDelegate{
    func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
        let cell:CustomCell = collectionView.cellForItem(at: indexPath)! as! ViewController.CustomCell
        print("SELECTED CELL: \(cell.label.text!)")
        return true
    }

}

Multi-Directional Scroll CustomCollectionViewLayout

的代码
import UIKit

class CustomCollectionViewLayout:UICollectionViewFlowLayout {
    let CELL_HEIGHT = 50.0
    let CELL_WIDTH = 80.0
    let STATUS_BAR = UIApplication.shared.statusBarFrame.height

    var cellAttrsDictionary = Dictionary<IndexPath, UICollectionViewLayoutAttributes>()

    var contentSize = CGSize.zero

    var dataSourceDidUpdate = true

    override var collectionViewContentSize : CGSize {
        return self.contentSize
    }

    override func prepare() {



        dataSourceDidUpdate = false
        cellAttrsDictionary.removeAll()

        if let sectionCount = collectionView?.numberOfSections, sectionCount > 0 {
            for section in 0...sectionCount-1 {

                if let rowCount = collectionView?.numberOfItems(inSection: section), rowCount > 0 {
                    for item in 0...rowCount-1 {

                        let cellIndex = IndexPath(item: item, section: section)
                        let xPos = Double(item) * CELL_WIDTH
                        let yPos = Double(section) * CELL_HEIGHT

                        let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex)
                        cellAttributes.frame = CGRect(x: xPos, y: yPos, width: CELL_WIDTH, height: CELL_HEIGHT)

                        if section == 0 && item == 0 {
                            cellAttributes.zIndex = 4
                        } else if section == 0 {
                            cellAttributes.zIndex = 3
                        } else if item == 0 {
                            cellAttributes.zIndex = 2
                        } else {
                            cellAttributes.zIndex = 1
                        }

                        cellAttrsDictionary[cellIndex] = cellAttributes

                    }
                }

            }
        }

        let contentWidth = Double(collectionView!.numberOfItems(inSection: 0)) * CELL_WIDTH
        let contentHeight = Double(collectionView!.numberOfSections) * CELL_HEIGHT
        self.contentSize = CGSize(width: contentWidth, height: contentHeight)

    }


    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

        var attributesInRect = [UICollectionViewLayoutAttributes]()

        for cellAttributes in cellAttrsDictionary.values {
            if rect.intersects(cellAttributes.frame) {
                attributesInRect.append(cellAttributes)
            }
        }

        return attributesInRect
    }

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        return cellAttrsDictionary[indexPath]!
    }

    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return true
    }
}

0 个答案:

没有答案