垂直方向のUICollectionView
があり、各セルがself.view.frame
全体を占めています。上にスワイプして次のセルに簡単に移動できますが、ボタンを押すだけで同じことを実行したいと思います。
私は使用してみました:
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
そして:
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated
これらは機能しますが、現在のセルを一時的に「ホワイトアウト」してnextCellを表示し、スワイプすると遷移中に両方のセルが表示されます。
理想的には私が使いたい:
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated
しかし、nextCellのindexPath
...にアクセスする方法がわかりません。試しました。
NSIndexPath *nextIndexPath = [_collectionView indexPathForItemAtPoint:CGPointMake(25, (_collectionView.frame.size.height-25)*(_currentIndexRowForCellOnScreen+1))];
ここで、_currentIndexRowForCellOnScreen
は、次の画面に最初に表示されたUICollectionView
のindexPath.row
です。
- (UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
しかし、私がそれを入れたとき:
- (NSIndexPath *)indexPathForCell:(UICollectionViewCell *)cell
最初のセルの後にNULLを返し、アニメーション化しません。
どんな方向でも大歓迎です。お時間をいただきありがとうございます。
CollectionViewに含まれるセクションが1つだけであり、各アイテムがフレーム全体を占めるとすると、次のようなことができます。
NSArray *visibleItems = [self.collectionView indexPathsForVisibleItems];
NSIndexPath *currentItem = [visibleItems objectAtIndex:0];
NSIndexPath *nextItem = [NSIndexPath indexPathForItem:currentItem.item + 1 inSection:currentItem.section];
[self.collectionView scrollToItemAtIndexPath:nextItem atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
これがSwiftバージョンです
Swift 2.x:
let visibleItems: NSArray = self.collectionView.indexPathsForVisibleItems()
let currentItem: NSIndexPath = visibleItems.objectAtIndex(0) as! NSIndexPath
let nextItem: NSIndexPath = NSIndexPath(forRow: currentItem.item + 1, inSection: 0)
self.collectionView.scrollToItemAtIndexPath(nextItem, atScrollPosition: .Top, animated: true)
Swift 3.x
let visibleItems: NSArray = self.collectionView.indexPathsForVisibleItems as NSArray
let currentItem: IndexPath = visibleItems.object(at: 0) as! IndexPath
let nextItem: IndexPath = IndexPath(item: currentItem.item + 1, section: 0)
self.collectionView.scrollToItem(at: nextItem, at: .top, animated: true)
これは私が遭遇した最善のアプローチです。トリックは、次のオブジェクトを含むフレームまでスクロールすることです。コードを参照してください
@IBAction func actionPreviousFriends(_ sender: Any) {
let collectionBounds = self.collectionView.bounds
let contentOffset = CGFloat(floor(self.collectionView.contentOffset.x - collectionBounds.size.width))
self.moveToFrame(contentOffset: contentOffset)
}
/* -------------- display next friends action ----------------*/
@IBAction func actionNextFriends(_ sender: Any) {
let collectionBounds = self.collectionView.bounds
let contentOffset = CGFloat(floor(self.collectionView.contentOffset.x + collectionBounds.size.width))
self.moveToFrame(contentOffset: contentOffset)
}
func moveToFrame(contentOffset : CGFloat) {
let frame: CGRect = CGRect(x : contentOffset ,y : self.collectionView.contentOffset.y ,width : self.collectionView.frame.width,height : self.collectionView.frame.height)
self.collectionView.scrollRectToVisible(frame, animated: true)
}
Swift 4.1回答
let visibleItems = self.collectionView.indexPathsForVisibleItems
let currentItem = visibleItems.first
let nextRow = (currentItem?.row)! + visibleItems.count
if nextRow < elementArray.count {
let nextIndexPath = IndexPath.init(row: nextRow, section: (currentItem?.section)!)
self.collectionView.scrollToItem(at: nextIndexPath, at: UICollectionViewScrollPosition.left, animated: true)
} else {
let nextIndexPath = IndexPath.init(row: 0, section: (currentItem?.section)!)
self.collectionView.scrollToItem(at: nextIndexPath, at: UICollectionViewScrollPosition.right, animated: true)
}
要件とスキップする行数に応じてスクロール位置を変更します(ここではスキップしましたvisibleItems.count
)
Swift 5:たとえば、go + 1 next
var index:Int = self.collectionView.indexPathsForVisibleItems.first!.row
index = index + 1
self.collectionView.scrollToItem(at: IndexPath(row: index, section: 0), at: UICollectionView.ScrollPosition.right, animated: true)