UIScrollView的delegate方法妙用之让UICollectionView滑动到某个你想要的位置
生活随笔
收集整理的這篇文章主要介紹了
UIScrollView的delegate方法妙用之让UICollectionView滑动到某个你想要的位置
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一個(gè)UICollectionView有好多個(gè)cell,滑動(dòng)一下,誰(shuí)也不知道會(huì)停留在哪個(gè)cell,滑的快一點(diǎn),就會(huì)多滑一段距離,反之則會(huì)滑的比較近,這正是UIScrollview用戶(hù)體驗(yàn)好的地方。 如果想要UICollectionView停留到某個(gè)cell的位置,可以用 - (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated; 這個(gè)方法,還能用scrollPosition這個(gè)參數(shù)控制cell具體停留在上下左右中到底哪個(gè)位置。 那么問(wèn)題來(lái)了:如果我只是隨便滑了一下,我也不知道它會(huì)停在位于哪個(gè)indexPath的cell上,但不管它停在哪個(gè)cell上,我都希望這個(gè)cell剛好在屏幕中間,應(yīng)該怎么辦呢?(這個(gè)場(chǎng)景在coverFlow的效果里比較常見(jiàn)) 之前知道的做法是: 在scrollViewDidEndDecelerating或其他delegate方法里,通過(guò)當(dāng)前 contentOffset 計(jì)算最近的整數(shù)頁(yè)及其對(duì)應(yīng)的 contentOffset,然后通過(guò)動(dòng)畫(huà)移動(dòng)到這個(gè)位置。 但是這個(gè)做法有問(wèn)題,就是動(dòng)畫(huà)不連貫,完全沒(méi)有“剛好停到那里”的感覺(jué)。 今天在想有沒(méi)有其他更好的辦法時(shí),突然發(fā)現(xiàn)一個(gè)之前從來(lái)沒(méi)用功的方法: - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset NS_AVAILABLE_IOS(5_0); 一看這參數(shù)名,再看看這文檔,真是讓人喜不自禁吶!這不就是讓scrollView“剛好停到某個(gè)位置”的方法嘛!!!(系統(tǒng)5.0就提供了,現(xiàn)在才看到。。。。。。) targetContentOffset 是個(gè)指針,可以修改這個(gè)參數(shù)的值,讓scrollView最終停止在目標(biāo)位置。 (2016年12月7日更新) 注意:scrollView的pagingEnable屬性必須為NO時(shí)這個(gè)方法才會(huì)被調(diào)用。 感謝@?ZeroOnet?評(píng)論中指出,這個(gè)方法在pagingEnable==YES的時(shí)候也會(huì)調(diào)用; 但是pagingEnable的效果會(huì)覆蓋這個(gè)方法的效果,達(dá)不到我們想要的“剛好停到指定位置的效果”,所以還是需要注意將pagingEnable設(shè)置為NO! 例: - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
??? CGPoint originalTargetContentOffset = CGPointMake(targetContentOffset->x, targetContentOffset->y);
??? CGPoint targetCenter = CGPointMake(originalTargetContentOffset.x + CGRectGetWidth(self.collectionView.bounds)/2, CGRectGetHeight(self.collectionView.bounds) / 2);
??? NSIndexPath *indexPath = nil;
??? NSInteger i = 0;
??? while (indexPath == nil) {
??????? targetCenter = CGPointMake(originalTargetContentOffset.x + CGRectGetWidth(self.collectionView.bounds)/2 + 10*i, CGRectGetHeight(self.collectionView.bounds) / 2);
??????? indexPath = [self.collectionView indexPathForItemAtPoint:targetCenter];
??????? i++;
??? }
??? self.selectedIndex = indexPath;
??? //這里用attributes比用cell要好很多,因?yàn)閏ell可能因?yàn)椴辉谄聊环秶鷥?nèi)導(dǎo)致cellForItemAtIndexPath返回nil
??? UICollectionViewLayoutAttributes *attributes = [self.collectionView.collectionViewLayout layoutAttributesForItemAtIndexPath:indexPath];
??? if (attributes) {
??????? *targetContentOffset = CGPointMake(attributes.center.x - CGRectGetWidth(self.collectionView.bounds)/2, originalTargetContentOffset.y);
??? } else {
??????? DLog(@"center is %@; indexPath is {%@, %@}; cell is %@",NSStringFromCGPoint(targetCenter), @(indexPath.section), @(indexPath.item), attributes);
??? }
??? } 這樣scrollView就會(huì)逐漸減速,最終停止在itemCenterOffsetWithOriginalTargetContentOffset方法算出來(lái)的位置上了,效果杠杠的~ 本來(lái)以為這個(gè)方法沒(méi)多少人知道,結(jié)果百度一搜,發(fā)現(xiàn)原來(lái)已經(jīng)有大神寫(xiě)過(guò)詳細(xì)的文章了(http://tech.glowing.com/cn/practice-in-uiscrollview/),這個(gè)就當(dāng)記錄一下吧 另外發(fā)現(xiàn)一個(gè)直接用NSObject就實(shí)現(xiàn)類(lèi)似效果的庫(kù):https://github.com/nicklockwood/iCarousel ? 乍看之下沒(méi)看懂。。。等有空再仔細(xì)研究 更新(2015-06-19) 原來(lái)UICollectionViewLayout已經(jīng)提供了兩個(gè)方法可以實(shí)現(xiàn)這個(gè)功能: - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity; - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset NS_AVAILABLE_IOS(7_0); 效果與上面的delegate方法完全一樣,不過(guò)這個(gè)是UICollectionViewLayout的方法,需要在自己的layout子類(lèi)里重載。 好處是:這樣就不用再在viewController里寫(xiě)scrollView的delegate方法了,viewController更加簡(jiǎn)潔;跟布局相關(guān)的代碼都轉(zhuǎn)移到了layout的類(lèi)中? ?
??? CGPoint originalTargetContentOffset = CGPointMake(targetContentOffset->x, targetContentOffset->y);
??? CGPoint targetCenter = CGPointMake(originalTargetContentOffset.x + CGRectGetWidth(self.collectionView.bounds)/2, CGRectGetHeight(self.collectionView.bounds) / 2);
??? NSIndexPath *indexPath = nil;
??? NSInteger i = 0;
??? while (indexPath == nil) {
??????? targetCenter = CGPointMake(originalTargetContentOffset.x + CGRectGetWidth(self.collectionView.bounds)/2 + 10*i, CGRectGetHeight(self.collectionView.bounds) / 2);
??????? indexPath = [self.collectionView indexPathForItemAtPoint:targetCenter];
??????? i++;
??? }
??? self.selectedIndex = indexPath;
??? //這里用attributes比用cell要好很多,因?yàn)閏ell可能因?yàn)椴辉谄聊环秶鷥?nèi)導(dǎo)致cellForItemAtIndexPath返回nil
??? UICollectionViewLayoutAttributes *attributes = [self.collectionView.collectionViewLayout layoutAttributesForItemAtIndexPath:indexPath];
??? if (attributes) {
??????? *targetContentOffset = CGPointMake(attributes.center.x - CGRectGetWidth(self.collectionView.bounds)/2, originalTargetContentOffset.y);
??? } else {
??????? DLog(@"center is %@; indexPath is {%@, %@}; cell is %@",NSStringFromCGPoint(targetCenter), @(indexPath.section), @(indexPath.item), attributes);
??? }
??? } 這樣scrollView就會(huì)逐漸減速,最終停止在itemCenterOffsetWithOriginalTargetContentOffset方法算出來(lái)的位置上了,效果杠杠的~ 本來(lái)以為這個(gè)方法沒(méi)多少人知道,結(jié)果百度一搜,發(fā)現(xiàn)原來(lái)已經(jīng)有大神寫(xiě)過(guò)詳細(xì)的文章了(http://tech.glowing.com/cn/practice-in-uiscrollview/),這個(gè)就當(dāng)記錄一下吧 另外發(fā)現(xiàn)一個(gè)直接用NSObject就實(shí)現(xiàn)類(lèi)似效果的庫(kù):https://github.com/nicklockwood/iCarousel ? 乍看之下沒(méi)看懂。。。等有空再仔細(xì)研究 更新(2015-06-19) 原來(lái)UICollectionViewLayout已經(jīng)提供了兩個(gè)方法可以實(shí)現(xiàn)這個(gè)功能: - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity; - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset NS_AVAILABLE_IOS(7_0); 效果與上面的delegate方法完全一樣,不過(guò)這個(gè)是UICollectionViewLayout的方法,需要在自己的layout子類(lèi)里重載。 好處是:這樣就不用再在viewController里寫(xiě)scrollView的delegate方法了,viewController更加簡(jiǎn)潔;跟布局相關(guān)的代碼都轉(zhuǎn)移到了layout的類(lèi)中? ?
轉(zhuǎn)載于:https://www.cnblogs.com/Phelthas/p/4584645.html
總結(jié)
以上是生活随笔為你收集整理的UIScrollView的delegate方法妙用之让UICollectionView滑动到某个你想要的位置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python 学习笔记10
- 下一篇: 系统怎么刻录到u盘 系统教程:U盘刻录方