Почему функция CollectionView вызывается дважды в Swift? - PullRequest
0 голосов
/ 07 февраля 2020

У меня проблемы с вызовом функции 2 раза. Из-за этого значение в PageView не установлено должным образом, потому что значение индекса не является правильным. Как вы можете контролировать это правильно?

ViewController.swift

class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var pageView: UIPageControl!
    @IBOutlet var guideView: UIView!
    var step : Int! = 0
    var beforeStep : Int! = 0

    var imageArray = [UIImage(named: "swipe1"),
                      UIImage(named: "swipe2"),
                      UIImage(named: "swipe3"),
                      UIImage(named: "swipe4"),
                      UIImage(named: "swipe5")]


    override func viewDidLoad() {
        super.viewDidLoad()
        pageView.numberOfPages = imageArray.count
        pageView.currentPage = 0
        pageView.currentPageIndicatorTintColor = UIColor.color(.dacColor)
        pageView.pageIndicatorTintColor = UIColor.gray
        view.backgroundColor = UIColor(red: CGFloat(252.0/255.0), green: CGFloat(251.0/255.0), blue: CGFloat(245.0/255.0), alpha: CGFloat(1.0))
        collectionView.backgroundColor = UIColor(red: CGFloat(252.0/255.0), green: CGFloat(251.0/255.0), blue: CGFloat(245.0/255.0), alpha: CGFloat(1.0))
    }
}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return imageArray.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        if let vc = cell.viewWithTag(111) as? UIImageView {
            vc.image = imageArray[indexPath.row]
        }
        if let ab = guideView.viewWithTag(222) as? UIPageControl {
            ab.currentPage = indexPath.row - 1
        }
        return cell
    }
}

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let size = collectionView.frame.size
        return CGSize(width: size.width, height: size.height)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
}

проблематика c функциональная часть

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        if let vc = cell.viewWithTag(111) as? UIImageView {
            vc.image = imageArray[indexPath.row]
        }
        if let ab = guideView.viewWithTag(222) as? UIPageControl {
            ab.currentPage = indexPath.row - 1
        }
        return cell
    }

CollectionView в StoryBoard

enter image description here

Просмотр списка в раскадровке

enter image description here

Я хочу, чтобы PageController был отмечен в соответствии с местоположением изображения.

Кто-нибудь решил ту же проблему, что и я?

Ответы [ 2 ]

2 голосов
/ 07 февраля 2020

В представлении коллекции go для макета и выбора пользовательского:

class CustomCollectionViewFlowLayout: UICollectionViewFlowLayout
{
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint
{
    if let collectionViewBounds = self.collectionView?.bounds
    {
        let halfWidthOfVC = collectionViewBounds.size.width * 0.5
        let proposedContentOffsetCenterX = proposedContentOffset.x + halfWidthOfVC
        if let attributesForVisibleCells = self.layoutAttributesForElements(in: collectionViewBounds)
        {
            var candidateAttribute : UICollectionViewLayoutAttributes?
            for attributes in attributesForVisibleCells
            {
                let candAttr : UICollectionViewLayoutAttributes? = candidateAttribute
                if candAttr != nil
                {
                    let a = attributes.center.x - proposedContentOffsetCenterX
                    let b = candAttr!.center.x - proposedContentOffsetCenterX
                    if fabs(a) < fabs(b)
                    {
                        candidateAttribute = attributes
                    }
                }
                else
                {
                    candidateAttribute = attributes
                    continue
                }
            }

            if candidateAttribute != nil
            {
                return CGPoint(x: candidateAttribute!.center.x - halfWidthOfVC, y: proposedContentOffset.y);
            }
        }
    }
    return CGPoint.zero
}
}

, а затем в делегате:

 func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    var visibleRect = CGRect()

    visibleRect.origin = Collections.contentOffset
    visibleRect.size = Collections.bounds.size

    let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)

    guard let indexPath = Collections.indexPathForItem(at: visiblePoint) else { return }


    print(indexPath.item)

}
2 голосов
/ 07 февраля 2020

collectionView(_:cellForItemAt:) - это метод делегата представления коллекции, который вызывается более одного раза, и существует множество факторов, которые инициируют вызов, например:

  1. Количество видимых количество ячеек, в зависимости от высоты коллекции

  2. При прокрутке ячеек для повторного их использования

Или триггеры для изменения / обновления sh коллекция вроде:

reloadData(), reloadItems(at:) или reloadSections(_:)

Возможно, вызов layoutIfNeeded() из представления, содержащего это представление коллекции.

и более ...

Дело в том, что функция, вызываемая более одного раза, вполне нормальна. Ваш ответ, вероятно, заключается в «Что вызывает вызов?»

РЕДАКТИРОВАТЬ :

Чтобы обновить страницу управления по индексу коллекции:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
   let visibleRect = CGRect(origin: yourCollectionView.contentOffset, size: yourCollectionView.bounds.size)
   let midPointOfVisibleRect = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
   if let visibleIndexPath = yourCollectionView.indexPathForItem(at: midPointOfVisibleRect) {
            yourPageControl.currentPage = visibleIndexPath.row
   }
}

Если вы используете UIPageViewController только для обозначения страницы, UIPageControl должно подойти. Возможно, вам также придется установить yourCollectionView.isPagingEnabled = true, так как это более подходит для элемента управления страницы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...