IPadアプリケーションで初めてUICollectionView
を使用しています。サイズとセルサイズが同じになるようにUICollectionView
を設定しました。つまり、一度にセルが表示されるのは一度だけです。
問題:ユーザーがUICollectionViewをスクロールするときに、どのセルが表示されているかを知る必要がある場合、変更時に他のUI要素を更新する必要があります。このデリゲートメソッドは見つかりませんでした。どうすればこれを達成できますか?
コード:
[self.mainImageCollection setTag:MAIN_IMAGE_COLLECTION_VIEW];
[self.mainImageCollection registerClass:[InspirationMainImageCollectionCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
[self.mainImageFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[self.mainImageFlowLayout setMinimumInteritemSpacing:0.0f];
[self.mainImageFlowLayout setMinimumLineSpacing:0.0f];
self.mainImageFlowLayout.minimumLineSpacing = 0;
[self.mainImageCollection setPagingEnabled:YES];
[self.mainImageCollection setShowsHorizontalScrollIndicator:NO];
[self.mainImageCollection setCollectionViewLayout:self.mainImageFlowLayout];
私が試したもの:
UICollectionView
がUIScrollView
に準拠しているため、ユーザースクロールがUIScrollViewDelegate
メソッドで終了する
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
しかし、上記の関数内でUICollectionView
の現在の表示セルインデックスを取得するにはどうすればよいですか?
メソッド[collectionView visibleCells]は、必要なすべてのvisibleCells配列を提供します。あなたが取得したいときにそれを使用してください
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
for (UICollectionViewCell *cell in [self.mainImageCollection visibleCells]) {
NSIndexPath *indexPath = [self.mainImageCollection indexPathForCell:cell];
NSLog(@"%@",indexPath);
}
}
indexPathsForVisibleItems
はほとんどの状況で機能する可能性がありますが、複数のインデックスパスを持つ配列を返すことがあり、必要なものを見つけるのが難しい場合があります。このような状況では、次のようなことができます。
CGRect visibleRect = (CGRect){.Origin = self.collectionView.contentOffset, .size = self.collectionView.bounds.size};
CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
NSIndexPath *visibleIndexPath = [self.collectionView indexPathForItemAtPoint:visiblePoint];
これは、コレクションビューの各アイテムが画面全体を占める場合に特に有効です。
Swiftバージョン
let visibleRect = CGRect(Origin: collectionView.contentOffset, size: collectionView.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
let visibleIndexPath = collectionView.indexPathForItem(at: visiblePoint)
Swift 2.2で結合されたワーキングアンサー:
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
var visibleRect = CGRect()
visibleRect.Origin = self.collectionView.contentOffset
visibleRect.size = self.collectionView.bounds.size
let visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect))
let visibleIndexPath: NSIndexPath = self.collectionView.indexPathForItemAtPoint(visiblePoint)
guard let indexPath = visibleIndexPath else { return }
print(indexPath)
}
Swift 3&Swift 4:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
var visibleRect = CGRect()
visibleRect.Origin = collectionView.contentOffset
visibleRect.size = collectionView.bounds.size
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
guard let indexPath = collectionView.indexPathForItem(at: visiblePoint) else { return }
print(indexPath)
}
完全を期すために、これは私のために働いてしまった方法です。 @Anthonyと@iAnのメソッドの組み合わせでした。
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
CGRect visibleRect = (CGRect){.Origin = self.collectionView.contentOffset, .size = self.collectionView.bounds.size};
CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
NSIndexPath *visibleIndexPath = [self.collectionView indexPathForItemAtPoint:visiblePoint];
NSLog(@"%@",visibleIndexPath);
}
UICollectionViewDelegateメソッドを使用するのがおそらく最善でしょう:(Swift 3)
// Called before the cell is displayed
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
print(indexPath.row)
}
// Called when the cell is displayed
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
print(indexPath.row)
}
他の人のために追加したいだけです:何らかの理由で、pagingEnabledでcollectionViewのprevious cellにスクロールしたときに、ユーザーに表示されるセルを取得できませんでした。
そこで、dispatch_async内にコードを挿入して、「空気」を与えます。
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
dispatch_async(dispatch_get_main_queue(), ^{
UICollectionViewCell * visibleCell= [[self.collectionView visibleCells] objectAtIndex:0];
[visibleCell doSomthing];
});
}
Swift 3.0の場合
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let visibleRect = CGRect(Origin: colView.contentOffset, size: colView.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
let indexPath = colView.indexPathForItem(at: visiblePoint)
}
Swift 3.0
可視セルのindexPathを提供する最も簡単なソリューション。
yourCollectionView.indexPathsForVisibleItems
indexpathの配列を返します。
このように配列から最初のオブジェクトを取得するだけです。
yourCollectionView.indexPathsForVisibleItems.first
Objective-Cでも問題なく動作するはずです。
var visibleCurrentCellIndexPath: IndexPath? {
for cell in self.collectionView.visibleCells {
let indexPath = self.collectionView.indexPath(for: cell)
return indexPath
}
return nil
}
このためにscrollViewDidEndDecelerating
:を使用できます
//@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
for (UICollectionViewCell *cell in [self.collectionView visibleCells]) {
NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell];
NSUInteger lastIndex = [indexPath indexAtPosition:[indexPath length] - 1];
NSLog(@"visible cell value %d",lastIndex);
}
}
@Anthonyの答えをSwift 3.に変換すると、私にとって完璧に機能しました。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
var visibleRect = CGRect()
visibleRect.Origin = yourCollectionView.contentOffset
visibleRect.size = yourCollectionView.bounds.size
let visiblePoint = CGPoint(x: CGFloat(visibleRect.midX), y: CGFloat(visibleRect.midY))
let visibleIndexPath: IndexPath? = yourCollectionView.indexPathForItem(at: visiblePoint)
print("Visible cell's index is : \(visibleIndexPath?.row)!")
}
このスニペットも確認してください
let isCellVisible = collectionView.visibleCells.map { collectionView.indexPath(for: $0) }.contains(inspectingIndexPath)
これは古い質問ですが、私の場合は...
- (void) scrollViewWillBeginDragging:(UIScrollView *)scrollView {
_m_offsetIdx = [m_cv indexPathForCell:m_cv.visibleCells.firstObject].row;
}
- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
_m_offsetIdx = [m_cv indexPathForCell:m_cv.visibleCells.lastObject].row;
}