我正在尝试处理UICollectionViewController中的界面方向更改。我想要实现的是,我想在接口旋转后拥有相同的 contentOffset。意思是,它应该根据边界变化的比例进行更改。
以纵向开头,内容偏移量为{ bounds.size.width * 2,0} ...
...应该导致横向内容偏移{{em> bounds.size.width * 2,0}(反之亦然)。
计算新偏移不是问题,但不知道,在何处(或何时)设置它以获得平滑的动画。我正在做的事情是使willRotateToInterfaceOrientation:duration:
中的布局无效并重置didRotateFromInterfaceOrientation:
中的内容偏移量:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration;
{
self.scrollPositionBeforeRotation = CGPointMake(self.collectionView.contentOffset.x / self.collectionView.contentSize.width,
self.collectionView.contentOffset.y / self.collectionView.contentSize.height);
[self.collectionView.collectionViewLayout invalidateLayout];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
{
CGPoint newContentOffset = CGPointMake(self.scrollPositionBeforeRotation.x * self.collectionView.contentSize.width,
self.scrollPositionBeforeRotation.y * self.collectionView.contentSize.height);
[self.collectionView newContentOffset animated:YES];
}
这会在旋转后更改内容偏移量。
如何在旋转期间设置它?我试图在willAnimateRotationToInterfaceOrientation:duration:
中设置新的内容偏移量,但这会导致一种非常奇怪的行为。
可以在GitHub上的项目中找到一个示例。
答案 0 :(得分:22)
以下是Swift 3.1中的代码,同样适用于Swift 4.2
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
{
super.viewWillTransition(to: size, with: coordinator)
let offset = self.collectionView?.contentOffset;
let width = self.collectionView?.bounds.size.width;
let index = round(offset!.x / width!);
let newOffset = CGPoint(x: index * size.width, y: offset!.y)
self.collectionView?.setContentOffset(newOffset, animated: false)
coordinator.animate(alongsideTransition: { (context) in
self.collectionView?.reloadData()
self.collectionView?.setContentOffset(newOffset, animated: false)
}, completion: nil)
}
答案 1 :(得分:18)
如果您需要的只是确保contentOffset以正确的位置结束,您可以创建UICollectionViewLayout的子类并实现 targetContentOffsetForProposedContentOffset:方法。例如,您可以执行以下操作来计算页面:
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
{
NSInteger page = ceil(proposedContentOffset.x / [self.collectionView frame].size.width);
return CGPointMake(page * [self.collectionView frame].size.width, 0);
}
但是你要面对的问题是那次过渡的动画非常奇怪。我在我的案子上做的事情(几乎与你的情况一样)是:
1)首先我设置单元格大小,可以通过 collectionView:layout:sizeForItemAtIndexPath:委托方法进行管理,如下所示:
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [self.view bounds].size;
}
请注意,[self.view bounds]将根据设备轮换而改变。
2)当设备即将旋转时,我将在集合视图顶部添加一个带有所有调整大小掩码的imageView。这个视图实际上会隐藏collectionView的怪异(因为它位于它之上)并且因为在动画块内部调用了willRotatoToInterfaceOrientation:方法,它将相应地旋转。我还根据显示的indexPath保留了下一个contentOffset,所以我可以在轮换完成后修复contentOffset:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
// Gets the first (and only) visible cell.
NSIndexPath *indexPath = [[self.collectionView indexPathsForVisibleItems] firstObject];
KSPhotoViewCell *cell = (id)[self.collectionView cellForItemAtIndexPath:indexPath];
// Creates a temporary imageView that will occupy the full screen and rotate.
UIImageView *imageView = [[UIImageView alloc] initWithImage:[[cell imageView] image]];
[imageView setFrame:[self.view bounds]];
[imageView setTag:kTemporaryImageTag];
[imageView setBackgroundColor:[UIColor blackColor]];
[imageView setContentMode:[[cell imageView] contentMode]];
[imageView setAutoresizingMask:0xff];
[self.view insertSubview:imageView aboveSubview:self.collectionView];
// Invalidate layout and calculate (next) contentOffset.
contentOffsetAfterRotation = CGPointMake(indexPath.item * [self.view bounds].size.height, 0);
[[self.collectionView collectionViewLayout] invalidateLayout];
}
请注意,我的UICollectionViewCell子类具有公共imageView属性。
3)最后,最后一步是将内容偏移“捕捉”到有效页面并删除临时图像视图。
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[self.collectionView setContentOffset:contentOffsetAfterRotation];
[[self.view viewWithTag:kTemporaryImageTag] removeFromSuperview];
}
答案 2 :(得分:13)
上面的“只是快照”回答对我来说不起作用,因为它经常没有在旋转之前的视图中结束。所以我派生了一个流程布局,使用焦点项(如果设置)来计算内容偏移量。我在willAnimateRotationToInterfaceOrientation中设置项目并在didRotateFromInterfaceOrientation中清除它。 IOS7上似乎需要插入调整,因为Collection视图可以在顶部栏下布局。
@interface HintedFlowLayout : UICollectionViewFlowLayout
@property (strong)NSIndexPath* pathForFocusItem;
@end
@implementation HintedFlowLayout
-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
{
if (self.pathForFocusItem) {
UICollectionViewLayoutAttributes* layoutAttrs = [self layoutAttributesForItemAtIndexPath:self.pathForFocusItem];
return CGPointMake(layoutAttrs.frame.origin.x - self.collectionView.contentInset.left, layoutAttrs.frame.origin.y-self.collectionView.contentInset.top);
}else{
return [super targetContentOffsetForProposedContentOffset:proposedContentOffset];
}
}
@end
答案 3 :(得分:11)
对于使用iOS 8+的用户,不推荐使用 willRotateToInterfaceOrientation 和 didRotateFromInterfaceOrientation 。
您现在应该使用以下内容:
/*
This method is called when the view controller's view's size is changed by its parent (i.e. for the root view controller when its window rotates or is resized).
If you override this method, you should either call super to propagate the change to children or manually forward the change to children.
*/
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Update scroll position during rotation animation
self.collectionView.contentOffset = (CGPoint){contentOffsetX, contentOffsetY};
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
// Whatever you want to do when the rotation animation is done
}];
}
斯威夫特3:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { (context:UIViewControllerTransitionCoordinatorContext) in
// Update scroll position during rotation animation
}) { (context:UIViewControllerTransitionCoordinatorContext) in
// Whatever you want to do when the rotation animation is done
}
}
答案 4 :(得分:7)
我认为正确的解决方案是覆盖子类UICollectionViewFlowLayout
来自文档:
在布局更新期间,或在布局之间转换时, 集合视图调用此方法为您提供机会 更改建议的内容偏移量以在动画结束时使用。 如果动画或转换可能会覆盖此方法 导致物品以不适合您的方式定位 设计。
答案 5 :(得分:4)
我使用fz的变体。回答(iOS 7&amp; 8):
轮换前:
轮换后:
删除图片视图。
@property (nonatomic) NSIndexPath *indexPath;
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
self.indexPathAfterRotation = [[self.collectionView indexPathsForVisibleItems] firstObject];
// Creates a temporary imageView that will occupy the full screen and rotate.
UIGraphicsBeginImageContextWithOptions(self.collectionView.bounds.size, YES, 0);
[self.collectionView drawViewHierarchyInRect:self.collectionView.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[imageView setFrame:[self.collectionView bounds]];
[imageView setTag:kTemporaryImageTag];
[imageView setBackgroundColor:[UIColor blackColor]];
[imageView setContentMode:UIViewContentModeCenter];
[imageView setAutoresizingMask:0xff];
[self.view insertSubview:imageView aboveSubview:self.collectionView];
[[self.collectionView collectionViewLayout] invalidateLayout];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[self.collectionView scrollToItemAtIndexPath:self.indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
[[self.view viewWithTag:kTemporaryImageTag] removeFromSuperview];
}
答案 6 :(得分:4)
要备份troppoli's解决方案,您可以在自定义类中设置偏移量,而无需担心记住在视图控制器中实现代码。旋转设备后应调用prepareForAnimatedBoundsChange
,然后finalizeAnimatedBoundsChange
完成旋转后调用。{/ 1}
@interface OrientationFlowLayout ()
@property (strong)NSIndexPath* pathForFocusItem;
@end
@implementation OrientationFlowLayout
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset {
if (self.pathForFocusItem) {
UICollectionViewLayoutAttributes* layoutAttrs = [self layoutAttributesForItemAtIndexPath:
self.pathForFocusItem];
return CGPointMake(layoutAttrs.frame.origin.x - self.collectionView.contentInset.left,
layoutAttrs.frame.origin.y - self.collectionView.contentInset.top);
}
else {
return [super targetContentOffsetForProposedContentOffset:proposedContentOffset];
}
}
- (void)prepareForAnimatedBoundsChange:(CGRect)oldBounds {
[super prepareForAnimatedBoundsChange:oldBounds];
self.pathForFocusItem = [[self.collectionView indexPathsForVisibleItems] firstObject];
}
- (void)finalizeAnimatedBoundsChange {
[super finalizeAnimatedBoundsChange];
self.pathForFocusItem = nil;
}
@end
答案 7 :(得分:4)
这个问题也困扰了我。最高的投票回答对我来说似乎有些过于苛刻,所以我只是稍微贬低了一下,只是在旋转之前和之后分别更改了集合视图的alpha。我也没有为内容偏移更新设置动画。
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
self.collectionView.alpha = 0;
[self.collectionView.collectionViewLayout invalidateLayout];
self.scrollPositionBeforeRotation = CGPointMake(self.collectionView.contentOffset.x / self.collectionView.contentSize.width,
self.collectionView.contentOffset.y / self.collectionView.contentSize.height);
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
{
CGPoint newContentOffset = CGPointMake(self.scrollPositionBeforeRotation.x * self.collectionView.contentSize.width,
self.scrollPositionBeforeRotation.y * self.collectionView.contentSize.height);
[self.collectionView setContentOffset:newContentOffset animated:NO];
self.collectionView.alpha = 1;
}
相当顺畅,不那么黑客。
答案 8 :(得分:2)
在旋转界面方向后,UICollectionViewCell通常会移动到另一个位置,因为我们不会更新contentSize和contentOffset。
因此,可见的UICollectionViewCell始终不会位于预期的位置。
我们期望图像的可见UICollectionView如下
UICollectionView必须委托“UICollectionViewDelegateFlowLayout”的函数[collectionView sizeForItemAtIndexPath]。
你应该在这个函数中计算项目大小。
自定义UICollectionViewFlowLayout必须覆盖以下函数。
-(void)prepareLayout
。设置itemSize,scrollDirection等。
-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
。计算页码或计算可见内容偏移量。
-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
。返回视觉内容偏移。
-(CGSize)collectionViewContentSize
。返回collectionView的总内容大小。
您的viewController必须覆盖“willRotateToInterfaceOrientation”并在此函数中 你应该调用函数[XXXCollectionVew.collectionViewLayout invalidateLayout];
但是在iOS 9中不推荐使用「willRotateToInterfaceOrientation」,或者你可以以不同的方式调用函数[XXXCollectionVew.collectionViewLayout invalidateLayout]。
以下是一个例子: https://github.com/bcbod2002/CollectionViewRotationTest
答案 9 :(得分:2)
这项工作就像一个魅力:
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return self.view.bounds.size;
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
int currentPage = collectionMedia.contentOffset.x / collectionMedia.bounds.size.width;
float width = collectionMedia.bounds.size.height;
[UIView animateWithDuration:duration animations:^{
[self.collectionMedia setContentOffset:CGPointMake(width * currentPage, 0.0) animated:NO];
[[self.collectionMedia collectionViewLayout] invalidateLayout];
}];
}
答案 10 :(得分:1)
我的工作是什么:
使用我的UICollectionViewDelegateFlowLayout
方法
func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize
{
return collectionView.bounds.size
}
之后我实现了willRotateToInterfaceOrientationToInterfaceOrientation:duration:
这样的
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval)
{
let currentPage = Int(collectionView.contentOffset.x / collectionView.bounds.size.width)
var width = collectionView.bounds.size.height
UIView.animateWithDuration(duration) {
self.collectionView.setContentOffset(CGPointMake(width * CGFloat(currentPage), 0.0), animated: false)
self.collectionView.collectionViewLayout.invalidateLayout()
}
}
以上代码位于 Swift ,但您明白了这一点并且很容易“翻译”
答案 11 :(得分:1)
如果发现使用targetContentOffsetForProposedContentOffset在所有场景中都不起作用,并且使用didRotateFromInterfaceOrientation的问题是它提供了可视化工件。我完美的代码如下:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
_indexPathOfFirstCell = [self indexPathsForVisibleItems].firstObject;
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
if (_indexPathOfFirstCell) {
[UIView performWithoutAnimation:^{
[self scrollToItemAtIndexPath:self->_indexPathOfFirstCell atScrollPosition:UICollectionViewScrollPositionTop animated:NO];
}];
_indexPathOfFirstCell = nil;
}
}
关键是使用willRotateToInterfaceOrientation方法来确定视图中要滚动到的部分,并且当视图更改其大小时,willAnimationRotationToInterfaceOrientation将重新计算它(当框架调用此方法时,边界已经更改)并实际滚动到没有动画的新位置。在我的代码中,我使用第一个可视单元格的索引路径来执行此操作,但contentOffset.y / contentSize.height的百分比也会以稍微不同的方式完成工作。
答案 12 :(得分:1)
在Swift 3中。
你应该在通过indexPath.item,x坐标或其他东西旋转之前跟踪正在呈现的单元格项目(页面)。 然后,在你的UICollectionView:
中override func collectionView(_ collectionView: UICollectionView, targetContentOffsetForProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint {
let page:CGFloat = pageNumber // your tracked page number eg. 1.0
return CGPoint(x: page * collectionView.frame.size.width, y: -(topInset))
//the 'y' value would be '0' if you don't have any top EdgeInset
}
在我的情况下,我使viewDidLayoutSubviews()中的布局无效,因此collectionView.frame.size.width是已旋转的collectionVC视图的宽度。
答案 13 :(得分:0)
“只是快照”答案是正确的方法,并且不需要IMO快照覆盖的额外平滑。但是,有一个问题可以解释为什么有些人会发现在某些情况下没有滚动到正确的页面。计算页面时,您需要使用高度而不是宽度。为什么?因为视图几何体已经在调用targetContentOffsetForProposedContentOffset时旋转,所以宽度现在是高度。四舍五入比天花板更明智。所以:
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
{
NSInteger page = round(proposedContentOffset.x / self.collectionView.bounds.size.height);
return CGPointMake(page * self.collectionView.bounds.size.width, 0);
}
答案 14 :(得分:0)
我用以下步骤解决了这个问题:
以下是演示上述步骤的代码模板:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration;
{
//Calculating Current IndexPath
CGRect visibleRect = (CGRect){.origin = self.yourCollectionView.contentOffset, .size = self.yourCollectionView.bounds.size};
CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
self.currentIndexPath = [self.yourCollectionView indexPathForItemAtPoint:visiblePoint];
//Disable Scrolling and Pagination
[self disableScrolling];
//Applying New Flow Layout
[self setupNewFlowLayout];
//Enable Scrolling and Pagination
[self enableScrolling];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
{
//You can also call this at the End of `willRotate..` method.
//Scrolling UICollectionView to current Index Path
[self.yourCollectionView scrollToItemAtIndexPath:self.currentIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO];
}
- (void) disableScrolling
{
self.yourCollectionView.scrollEnabled = false;
self.yourCollectionView.pagingEnabled = false;
}
- (void) enableScrolling
{
self.yourCollectionView.scrollEnabled = true;
self.yourCollectionView.pagingEnabled = true;
}
- (void) setupNewFlowLayout
{
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
flowLayout.minimumInteritemSpacing = 0;
flowLayout.minimumLineSpacing = 0;
[flowLayout setItemSize:CGSizeMake(EXPECTED_WIDTH, EXPECTED_HEIGHT)];
[self.yourCollectionView setCollectionViewLayout:flowLayout animated:YES];
[self.yourCollectionView.collectionViewLayout invalidateLayout];
}
我希望这会有所帮助。
答案 15 :(得分:0)
我在animateAlongsideTransition
中的animateAlongsideTransition
块中遇到了一些麻烦(请参见下面的代码)。
请注意,在动画过程中(而不是之前)调用它 我的任务是通过滚动到顶部可见的行来更新表格视图滚动位置(当设备旋转时表格视图单元向上移动时,我遇到了iPad上的问题,因此我找到了解决该问题的方法)。但也许对contentOffset也会有用。
我试图通过以下方式解决问题:
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
__weak TVChannelsListTableViewController *weakSelf = self;
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
weakSelf.topVisibleRowIndexPath = [[weakSelf.tableView indexPathsForVisibleRows] firstObject];
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
[weakSelf.tableView scrollToRowAtIndexPath:weakSelf.topVisibleRowIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
}];
}
但是没有用。例如,最高cel的索引路径为(0,20)。但是,当调用设备旋转animateAlongsideTransition块并且[[weakSelf.tableView indexPathsForVisibleRows] firstObject]返回索引路径(0,27)。
我认为问题出在到weakSelf
的索引路径中。因此,为解决此问题,我将self.topVisibleRowIndexPath
移到了[coordinator animateAlongsideTransition: completion]
方法调用之前:
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
__weak TVChannelsListTableViewController *weakSelf = self;
self.topVisibleRowIndexPath = [[weakSelf.tableView indexPathsForVisibleRows] firstObject];
[coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
[weakSelf.tableView scrollToRowAtIndexPath:weakSelf.topVisibleRowIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
}];
}
我发现的另一个有趣的事情是,当未重新定义方法willRotateToInterfaceOrientation
时,不推荐使用的方法willRotateToInterfaceOrientation
和viewWillTransitionToSize
在iOS 8.0以后的版本中仍然可以成功调用。
因此,在我的情况下,解决此问题的另一种方法是使用不推荐使用的方法,而不是新方法。我认为这不是正确的解决方案,但是可以尝试其他方法是否无效:)
答案 16 :(得分:0)
Swift 4.2子类:
class RotatableCollectionViewFlowLayout: UICollectionViewFlowLayout {
private var focusedIndexPath: IndexPath?
override func prepare(forAnimatedBoundsChange oldBounds: CGRect) {
super.prepare(forAnimatedBoundsChange: oldBounds)
focusedIndexPath = collectionView?.indexPathsForVisibleItems.first
}
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint {
guard let indexPath = focusedIndexPath
, let attributes = layoutAttributesForItem(at: indexPath)
, let collectionView = collectionView else {
return super.targetContentOffset(forProposedContentOffset: proposedContentOffset)
}
return CGPoint(x: attributes.frame.origin.x - collectionView.contentInset.left,
y: attributes.frame.origin.x - collectionView.contentInset.left)
}
override func finalizeAnimatedBoundsChange() {
super.finalizeAnimatedBoundsChange()
focusedIndexPath = nil
}
}
答案 17 :(得分:0)
我有一个类似的情况,我使用这个
- (void)setFrame:(CGRect)frame
{
CGFloat currentWidth = [self frame].size.width;
CGFloat offsetModifier = [[self collectionView] contentOffset].x / currentWidth;
[super setFrame:frame];
CGFloat newWidth = [self frame].size.width;
[[self collectionView] setContentOffset:CGPointMake(offsetModifier * newWidth, 0.0f) animated:NO];
}
这是一个包含collectionView的视图。 在superview我也这样做
- (void)setFrame:(CGRect)frame
{
UICollectionViewFlowLayout *collectionViewFlowLayout = (UICollectionViewFlowLayout *)[_collectionView collectionViewLayout];
[collectionViewFlowLayout setItemSize:frame.size];
[super setFrame:frame];
}
这是将单元格大小调整为全屏(准确的全视图;))。如果你不这样做,可能会出现很多关于单元格大小比集合视图大的错误消息,并且没有定义这个行为并且bla bla bla .....
这些to方法当然可以合并到collectionview的一个子类中,也可以合并到包含collectionview的视图中,但对于我当前的项目来说,这是合乎逻辑的方法。
答案 18 :(得分:0)
使用<CollectionViewDelegateFlowLayout>
并在方法didRotateFromInterfaceOrientation:
中重新加载CollectionView的数据。
实施collectionView:layout:sizeForItemAtIndexPath:
的{{1}}方法,并在方法中验证接口方向并应用每个单元格的自定义大小。
<CollectionViewDelegateFlowLayout>
答案 19 :(得分:0)
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize pnt = CGSizeMake(70, 70);
return pnt; }
-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
// UIEdgeInsetsMake(<#CGFloat top#>, <#CGFloat left#>, <#CGFloat bottom#>, <#CGFloat right#>)
return UIEdgeInsetsMake(3, 0, 3, 0); }
这样您就可以调整内容偏移量和单元格的大小。
答案 20 :(得分:0)
我的项目存在问题,我为UICollectionView使用了两种不同的布局。
mCustomCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"LandScapeCell" forIndexPath:indexPath];
theCustomCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"PortraitCell" forIndexPath:indexPath];
然后检查每个方向,并针对每个方向使用您的配置。
答案 21 :(得分:0)
我的方法是使用UICollectionViewFlowlayout对象。
如果水平滚动,则设置ojbect行间距。
[flowLayout setMinimumLineSpacing:26.0f];
如果它垂直滚动,则设置它的interitem间距。
[flowLayout setMinimumInteritemSpacing:0.0f];
请注意,旋转屏幕时其行为会有所不同。就我而言,我让它水平滚动,所以minimumlinespacing是26.0f。然后它转向横向方向似乎很可怕。我必须检查旋转并为该方向设置minimumlinespacing 0.0f以使其正确。
就是这样!简单。
答案 22 :(得分:0)
您可能希望在它(不正确)动画期间隐藏collectionView,并显示正确旋转的单元格的占位符视图。
对于一个简单的照片库,我找到了一种看起来非常好的方法。在这里看到我的答案: How to rotate a UICollectionView similar to the photos app and keep the current view centered?
答案 23 :(得分:-2)
您可能想尝试这个未经测试的代码:
- (void) willRotateToInterfaceOrientation: (UIInterfaceOrientation) toInterfaceOrientation
duration: (NSTimeInterval) duration
{
[UIView animateWithDuration: duration
animation: ^(void)
{
CGPoint newContentOffset = CGPointMake(self.scrollPositionBeforeRotation.x *
self.collectionView.contentSize.height,
self.scrollPositionBeforeRotation.y *
self.collectionView.contentSize.width);
[self.collectionView setContentOffset: newContentOffset
animated: YES];
}];
}