Ответ 1
Я думаю, это может помочь вам
UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
Затем вы можете получить доступ к местоположению через attributes.frame
Код ниже прокручивается в правую ячейку в UICollectionView
, но заголовок заголовка раздела скрывается за UINavigationBar
в моем случае. Я считаю, что вместо scrollRectToVisible
следует использовать scrollRectToVisible
, и мой вопрос в том, каков правильный способ вычисления CGRect
(y position), когда переменная numberOfRows
в заданном section
является переменной.
- (void)scrollToPricing:(NSUInteger)row {
[self.collectionView scrollToItemAtIndexPath:
[NSIndexPath indexPathForItem:0
inSection:row]
atScrollPosition:UICollectionViewScrollPositionTop
animated:YES];
}
Я думаю, это может помочь вам
UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
Затем вы можете получить доступ к местоположению через attributes.frame
Похоже, все ответы чересчур сложны. Это работает для меня:
let attributes = self.collectionView.collectionViewLayout.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: NSIndexPath(forItem: 0, inSection: section))
self.collectionView.setContentOffset(CGPointMake(0, attributes!.frame.origin.y - self.collectionView.contentInset.top), animated: true)
Swift 3:
if let attributes = collectionView.collectionViewLayout.layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindSectionHeader, at: IndexPath(item: 0, section: section)) {
collectionView.setContentOffset(CGPoint(x: 0, y: attributes.frame.origin.y - collectionView.contentInset.top), animated: true)
}
Сначала возьмите фрейм для заголовка в разделе:
- (CGRect)frameForHeaderForSection:(NSInteger)section {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:1 inSection:section];
UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
CGRect frameForFirstCell = attributes.frame;
CGFloat headerHeight = [self collectionView:_collectionView layout:_layout referenceSizeForHeaderInSection:section].height;
return CGRectOffset(frameForFirstCell, 0, -headerHeight);
}
Примечание. Я просто поставлю значение 1
для indexPath.item
. Возможно, вам придется изменить это на что-то подходящее для вашей реализации.
Затем прокрутите UIScrollView
до точки в верхней части заголовка:
- (void)scrollToTopOfSection:(NSInteger)section animated:(BOOL)animated {
CGRect headerRect = [self frameForHeaderForSection:section];
CGPoint topOfHeader = CGPointMake(0, headerRect.origin.y - _collectionView.contentInset.top);
[_collectionView setContentOffset:topOfHeader animated:animated];
}
Примечание: вы должны вычесть contentInset
, иначе он будет отброшен, и ваше прокрутка будет прокручиваться за панель состояния и/или панель навигации.
// scroll to selected index
NSIndexPath* cellIndexPath = [NSIndexPath indexPathForItem:0 inSection:sectionIndex];
UICollectionViewLayoutAttributes* attr = [self.collectionView.collectionViewLayout layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:cellIndexPath];
UIEdgeInsets insets = self.collectionView.scrollIndicatorInsets;
CGRect rect = attr.frame;
rect.size = self.collectionView.frame.size;
rect.size.height -= insets.top + insets.bottom;
CGFloat offset = (rect.origin.y + rect.size.height) - self.collectionView.contentSize.height;
if ( offset > 0.0 ) rect = CGRectOffset(rect, 0, -offset);
[self.collectionView scrollRectToVisible:rect animated:YES];
// [myCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:index_of_sec] atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
Below code will fix your problem, as i have faced same issue and used this solution developed by me instead of above commented code.
UICollectionViewLayoutAttributes *attributes = [myCollectionView layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:index_of_sec]];
CGRect rect = attributes.frame;
[myCollectionView setContentOffset:CGPointMake(myCollectionView.frame.origin.x, rect.origin.y - HEIGHT_OF_YOUR_HEADER) animated:YES];
Самый простой способ - использовать заголовок раздела frame.origin.x
и frame.origin.y
, а затем добавить заголовок раздела height
с помощью элемента height
, чтобы создать прокрутку CGRect
.
let sectionHeaderAttributes: UICollectionViewLayoutAttributes = self.collectionView.layoutAttributesForItem(at: scrollToIndexPath)!;
let itemAttributes: UICollectionViewLayoutAttributes = self.collectionView.layoutAttributesForSupplementaryElement(ofKind: UICollectionElementKindSectionHeader, at: scrollToIndexPath)!;
let combinedFrame: CGRect = CGRect(x: sectionHeaderAttributes.frame.origin.x, y: sectionHeaderAttributes.frame.origin.y, width: sectionHeaderAttributes.frame.width, height: sectionHeaderAttributes.frame.height + itemAttributes.frame.height);
collectionView.scrollRectToVisible(combinedFrame, animated: false);
Основываясь на ответе @pixelfreak
Swift 4.2
+ iOS 11 Safe Area
SUPPORT (для iPhone X и выше)if let attributes = collectionView.layoutAttributesForSupplementaryElement(ofKind: UICollectionView.elementKindSectionHeader, at: IndexPath(item: 0, section: section)) {
var offsetY = attributes.frame.origin.y - collectionView.contentInset.top
if #available(iOS 11.0, *) {
offsetY -= collectionView.safeAreaInsets.top
}
collectionView.setContentOffset(CGPoint(x: 0, y: offsetY), animated: true) // or animated: false
}
СЧАСТЛИВЫЙ КОДИРОВАНИЕ