2017-12-09 12 views
0

사용자가 선택할 수있는 다른 기간 (매일)이있는 collectionView가 있습니다. 각 항목의 크기는 collectionView 자체의 크기와 같습니다. 내가 뭘하려고 오전UICollectionView가 스크롤 된 후 표시된 항목에 대한 IndexPath를 업데이트하십시오.

@IBOutlet weak var periodCollectionView: UICollectionView! 
@IBOutlet weak var itemLabel: UILabel! 

let collectionValues = ["Day", "Week", "Month", "Year"] 
var currentVisibleItem: Int? 

override func viewDidLoad() { 
    super.viewDidLoad() 

} 

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

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PeriodName", for: indexPath) as? DisplayPeriodCollectionViewCell 
    else { 
     fatalError("Unable to cast collection view cell as DisplayPeriodCollectionViewCell") 
    } 

    cell.periodName.text = collectionValues[indexPath.item] 

    return cell 

} 

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

    return CGSize(width: width, height: height) 
} 

는 collectionView가 스크롤 한 후 현재 눈에 보이는 항목의 인덱스를 표시 할 정보 레이블을 얻을 수있다. 그녀는 코드입니다 : 내가 값은 런타임에 제대로 정의되어 있는지 확인하는 인쇄 문을 추가 한

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 

    let centerPoint = CGPoint(x: periodCollectionView.center.x + periodCollectionView.contentOffset.x, y: 1.0) 
    print("centerPoint: \(centerPoint)") 

    if let currentItemIndexPath = periodCollectionView.indexPathForItem(at: centerPoint) { 
     currentVisibleItem = currentItemIndexPath.item 
     print("index of current item: \(currentVisibleItem!)") 
     itemLabel.text = "\(currentVisibleItem!)" 
    } else { 
     print("could not get index of current item...") 
    } 

} 

, 그들은 모든 것이 괜찮 보여줍니다. 문제는 라벨이 항상 끝을 스크롤 한 후 해당 텍스트를 업데이트하지 않는다는 것입니다, 대신에 발생하는 새로운 스크롤을 기다립니다 :이 일어나는 이유를 알아낼 수 없습니다

enter image description here

-scrollViewDidEndDecelerating 쇼에 중단 점을 설정 모든 코드가 실행되기 때문에 레이블 텍스트에 어떤 문제가 있습니까?

UPD. 업데이트되지 않는 라벨 텍스트는 시뮬레이터 문제로 보입니다. 기기에서 실행 중일 때 라벨이 올바르게 업데이트됩니다.

+0

는'scrollViewDidEndScrollingAnimation (_ :'잘 작동 하는가? – vacawama

+0

나는 단지 시뮬레이터 문제가되는 것에 의존하지 않을 것이다. 타이밍 문제 일 수 있으며 기기에서 볼 수 없지만 느리고 빠른 기기에서 발생할 수 있습니다. – vacawama

+0

레이블 업데이트를 포함하여 컬렉션보기가 스크롤 될 때마다 모든 코드가 실행됩니다. 나는 breakpoint로 체크했다. 그러나 시뮬레이터에서 어떤 이유로 레이블 업데이트가 표시되지 않습니다. –

답변

2

은 당신이 사용할 수있는 귀하의 경우에는이

override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 
    let currentIndex = scrollView.contentOffset.x/CGFloat((itemWidth + interitemSpacing/2)) 
    print(currentIndex) 
} 
+0

이것은 색인을 얻는 훨씬 더 간단한 방법입니다. 힌트를 주셔서 감사합니다! 레이블 텍스트 업데이트 정보 - 시뮬레이터 문제 인 것 같습니다. 질문에 대한 업데이트 확인 –

+0

다른 시뮬레이터를 사용해 보셨습니까 아니면 재부팅하셨습니까? –

0

을 시도해보십시오 각 항목이 컬렉션 뷰와 같은 크기입니다

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

때문이다. 당신은 아직도 당신이 다음을 위임 기능에서 페이지 계산을 작성해야 스크롤 뷰 대리자를 사용하려면 :

func scrollViewDidEndDragging(UIScrollView, willDecelerate: Bool) 

func scrollViewDidEndDecelerating(UIScrollView) 

func scrollViewDidEndScrollingAnimation(UIScrollView) 
+0

'cellForItemAt' 메소드의 문제점은 현재 항목의 indexPath에 대해 예측할 수 없다는 것입니다. 앞으로 스크롤하면 곧 나오는 셀과 그 다음 셀에 대해 두 번 호출됩니다. 다시 스크롤하면 셀이 아직 스택에 있기 때문에 전혀 호출되지 않을 수 있습니다. –

+0

func tableView (UITableView, willDisplay : UITableViewCell, forRowAt : IndexPath)를 사용하려고 했습니까? –

+0

세 가지 스크롤 뷰 대리자 메서드를 모두 구현하면 gif에 표시된 화살표 버튼에 전원을 공급하는 데 도움이됩니다. 그것들은 콜렉션 아이템을 통해 반복하도록되어 있지만, 단일 scrollViewDidEndDecelerating 메소드는 그것들을 위해 작동하지 않았다. –