将UIScrollView Delegate和UICollectionView Delegate分配给同一个类

问题描述 投票:0回答:1

我有一个分页UIScrollView,每个页面都填充了不同的视图控制器。在scrollview上方是一个UICollectionView,充当菜单栏。滚动浏览滚动视图页面时,菜单栏会稍微移动一下。你可以从左边的gif看到。

将其委托设置为不同的类可以使一切正常工作,如左侧的gif所示。但是,将它们设置为同一个类会扰乱UICollectionViews的行为。

如何将他们的代表设置为同一个类?

import UIKit

class MenuView: UIView, UICollectionViewDataSource {

    let collcetionView: UICollectionView = {
        let view = UICollectionView()
        // Setup...
        return view
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupCollectionView()
        collcetionView.dataSource = self
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    fileprivate func setupCollectionView() {
        // Autolayout code...
    }

    // Datasource methods to populate collection view cells
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    // Populate cell code...
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        // Populate cell code...
    }
}


class MainView: UIView {
    // Contains paging scroll view and menu bar
    var menu: MenuView!

    let scrollView: UIScrollView = {
        let view = UIScrollView()
        // Setup...
        return view
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupMenu()
        setupScrollView()

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    fileprivate func setupScrollView() {
        // Autolayout code...
    }
    fileprivate func setupMenu() {
        menu = MenuView()
        // Autolayout code...
    }
}


class MainController: UIViewController, UIScrollViewDelegate, UICollectionViewDelegate {
    var mainView: MainView!

    override func loadView() {
        super.loadView()
        mainView = MainView()
        view = mainView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        mainView.scrollView.delegate = self
        mainView.menu.collcetionView.delegate = self // <<--- THIS IS WHAT BREAKS EVERYTHING
    }


func scrollViewDidScroll(_ scrollView: UIScrollView) {

        // Moving menu bar with page scroll
        mainView.menu.collectionView.contentOffset = CGPoint(x: scrollView.contentOffset.x/SCROLL_FACTOR - (firstIndexPosition/SCROLL_FACTOR - difference/2), y: 0)



        // Fade in and out highlighted state of menu bar cell
        let exactPage = (scrollView.contentOffset.x / SCREEN_WIDTH)
        let currentPage = (scrollView.contentOffset.x / SCREEN_WIDTH).rounded()
        let unitExact = currentPage - exactPage
        //print(String(format: "exact: %.2f, ", exactPage) + "current: \(currentPage), " + String(format: "unit: %.2f, ", unitExact))

        if exactPage > currentPage {
            // exact > current
            // fade out/in left icon
            // select current
            let unit = 0 - unitExact // from 0 - 0.5
            let cell = mainView.menu.collectionView.cellForItem(at: IndexPath(item: Int(currentPage), section: 0)) as! MenuBarCell
            let mapped = unit.map(from: 0.0...0.5, to: 0...149.0)
            print(cell)
            setCellColor(cell: cell, value: mapped)
        } else if exactPage < currentPage {
            // exact < current
            // fade out/in right icon
            // select current
            let unit = unitExact // from 0 - 0.5
            let cell = mainView.menu.collectionView.cellForItem(at: IndexPath(item: Int(currentPage), section: 0)) as! MenuBarCell
            let mapped = unit.map(from: 0.0...0.5, to: 0...149.0)
            setCellColor(cell: cell, value: mapped)
        } else if exactPage == currentPage {
            // exact = current
            // darken that icon
            // select current
        }
    }
}
ios swift uicollectionview contentoffset uicollectionviewdelegate
1个回答
0
投票

UICollectionViewUITableView继承自UIScrollView

如果将两个对象的scrollViewDidScroll设置为同一个类,则将为集合视图和scrollview调用delegate委托方法。

你需要检查为什么要调用scrollViewDidScroll并采取相应的行动。

最简单的方法是guard语句,如果没有为您感兴趣的滚动视图调用委托方法,则返回该语句。

如果您需要执行不同的代码,具体取决于所涉及的滚动视图,您可以使用一系列if语句或switch语句。

func scrollViewDidScroll(_ scrollView: UIScrollView) {

   guard scrollView == self.scrollView else {
       return
   }

    // Moving menu bar with page scroll
    mainView.menu.collectionView.contentOffset = CGPoint(x: scrollView.contentOffset.x/SCROLL_FACTOR - (firstIndexPosition/SCROLL_FACTOR - difference/2), y: 0)



    // Fade in and out highlighted state of menu bar cell
    let exactPage = (scrollView.contentOffset.x / SCREEN_WIDTH)
    let currentPage = (scrollView.contentOffset.x / SCREEN_WIDTH).rounded()
    let unitExact = currentPage - exactPage
    //print(String(format: "exact: %.2f, ", exactPage) + "current: \(currentPage), " + String(format: "unit: %.2f, ", unitExact))

    if exactPage > currentPage {
        // exact > current
        // fade out/in left icon
        // select current
        let unit = 0 - unitExact // from 0 - 0.5
        let cell = mainView.menu.collectionView.cellForItem(at: IndexPath(item: Int(currentPage), section: 0)) as! MenuBarCell
        let mapped = unit.map(from: 0.0...0.5, to: 0...149.0)
        print(cell)
        setCellColor(cell: cell, value: mapped)
    } else if exactPage < currentPage {
        // exact < current
        // fade out/in right icon
        // select current
        let unit = unitExact // from 0 - 0.5
        let cell = mainView.menu.collectionView.cellForItem(at: IndexPath(item: Int(currentPage), section: 0)) as! MenuBarCell
        let mapped = unit.map(from: 0.0...0.5, to: 0...149.0)
        setCellColor(cell: cell, value: mapped)
    } else if exactPage == currentPage {
        // exact = current
        // darken that icon
        // select current
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.