Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UICollectionView在屏幕加载时自动滚动到底部_Ios_Objective C_Uiscrollview_Uicollectionview - Fatal编程技术网

Ios UICollectionView在屏幕加载时自动滚动到底部

Ios UICollectionView在屏幕加载时自动滚动到底部,ios,objective-c,uiscrollview,uicollectionview,Ios,Objective C,Uiscrollview,Uicollectionview,我想知道当屏幕第一次加载时如何滚动到UICollectionView的底部。我可以在触摸状态栏时滚动到底部,但我希望在加载视图时也能自动滚动到底部。如果我想在触摸状态栏时滚动到底部,下面的选项可以正常工作 - (BOOL)scrollViewShouldScrollToTop:(UITableView *)tableView { NSLog(@"Detect status bar is touched."); [self scrollToBottom]; return NO; } -(void

我想知道当屏幕第一次加载时如何滚动到UICollectionView的底部。我可以在触摸状态栏时滚动到底部,但我希望在加载视图时也能自动滚动到底部。如果我想在触摸状态栏时滚动到底部,下面的选项可以正常工作

- (BOOL)scrollViewShouldScrollToTop:(UITableView *)tableView
{
NSLog(@"Detect status bar is touched.");
[self scrollToBottom];
return NO;
}

-(void)scrollToBottom
{//Scrolls to bottom of scroller
 CGPoint bottomOffset = CGPointMake(0, collectionViewReload.contentSize.height -     collectionViewReload.bounds.size.height);
 [collectionViewReload setContentOffset:bottomOffset animated:NO];
 }

我尝试在viewDidLoad中调用[self scrollToBottom]。这不管用。关于如何在加载视图时滚动到底部,您有什么想法吗?

请详细说明我的评论

viewDidLoad在元素可见之前调用,因此某些UI元素无法很好地操作。像在周围移动按钮但处理子视图这样的事情通常不起作用(比如滚动CollectionView)

当在ViewWillDisplay或ViewDidDisplay中调用时,这些操作中的大多数都会工作得最好。以下是Apple文档中的一个例外,它指出了重写这些方法时要做的一件重要事情:

您可以重写此方法以执行关联的其他任务 提出观点如果重写此方法,则必须调用 在您的实施过程中的某个时刻,这是一个非常好的选择。


超级调用通常在自定义实现之前调用。(因此是重写方法内部的第一行代码)。

获取最后一项的indexpath。然后

- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated

我发现在ViewWill中没有任何东西会起作用。我只能在ViewDidLayoutSubView中使用它:

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:endOfModel inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}

所以有一个类似的问题,这里有另一种方法来解决它,而不使用scrollToItemAtIndexPath

仅当内容大于图幅时,才会滚动到底部

使用scrollToItemAtIndexPath可能更好,但这只是另一种方法

CGFloat collectionViewContentHeight = myCollectionView.contentSize.height;
CGFloat collectionViewFrameHeightAfterInserts = myCollectionView.frame.size.height - (myCollectionView.contentInset.top + myCollectionView.contentInset.bottom);

if(collectionViewContentHeight > collectionViewFrameHeightAfterInserts) {
   [myCollectionView setContentOffset:CGPointMake(0, myCollectionView.contentSize.height - myCollectionView.frame.size.height) animated:NO];
}

对我来说,我找到了下一个解决方案:

在CollectionView中调用reloadData,并在main上使dcg滚动

 __weak typeof(self) wSelf = self;

 [wSelf.cv reloadData];
 dispatch_async(dispatch_get_main_queue(), ^{
 NSLog(@"HeightGCD:%@", @(wSelf.cv.contentSize.height));
 [wSelf.cv scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:50 inSection:0] atScrollPosition:UICollectionViewScrollPositionBottom animated:YES];
 });

Swift 3示例

let sectionNumber = 0
self.collectionView?.scrollToItem(at: //scroll collection view to indexpath
                                  NSIndexPath.init(row:(self.collectionView?.numberOfItems(inSection: sectionNumber))!-1, //get last item of self collectionview (number of items -1)
                                                   section: sectionNumber) as IndexPath //scroll to bottom of current section
                                , at: UICollectionViewScrollPosition.bottom, //right, left, top, bottom, centeredHorizontally, centeredVertically
                                animated: true)

问题可能是,即使您的集合视图在屏幕上,它也可能没有实际的
contentSize

如果在
视图中滚动显示
,则会显示
内容大小
,但在滚动之前,您的scollectionview会短暂显示内容

viewdilayoutsubviews
的问题是它被多次调用,因此需要添加一个丑陋的布尔值来限制滚动

我找到的最好的解决方案是强制在视图中显示布局

覆盖函数视图将出现(u动画:Bool){
超级。视图将显示(动画)
//在滚动到最新版本之前强制布局
collectionView.layoutIfNeeded()的
//现在你可以随意滚动
//例如,向右滚动
让偏移量=collectionView.contentSize.width-collectionView.bounds.size.width
collectionView.setContentOffSet(CGPoint(x:offset,y:0),动画:动画)
}

考虑您是否可以像这样使用
性能更新

private func reloadAndScrollToItem(at index: Int, animated: Bool) {
    collectionView.reloadData()
    collectionView.performBatchUpdates({
        self.collectionView.scrollToItem(at: IndexPath(item: index, section: 0),
                                         at: .bottom,
                                         animated: animated)
    }, completion: nil)
}

如果
index
是集合视图数据源中最后一个项目的索引,它将一直滚动到底。

所有这些对我来说都不是很好,我最终得到的结果是,它将适用于任何滚动视图

extension UIScrollView {
    func scrollToBottom(animated: Bool) {
        let y = contentSize.height - 1
        let rect = CGRect(x: 0, y: y + safeAreaInsets.bottom, width: 1, height: 1)
        scrollRectToVisible(rect, animated: animated)
    }
}

尝试在ViewWillDisplay中执行此操作,如果不起作用,请尝试ViewDidDisplay。太好了!!谢谢Joel,ViewDidDisplay可以正常工作。请注意,当导航回此视图控制器或方向更改后,视图将再次滚动到底部。如果需要的话,别忘了用适当的条件(可能是bools)来处理这个问题。你使用GCD来进入主线程,救了我一命。我有一个几乎无法追踪的bug,这显然是由于我试图在后台线程上滚动而引起的…我没有意识到我已打开。
scrollToItemAtIndexPath
滚动到最后一个单元格的底部,但是你的方法很好,滚动到单元格的底部+底部昆虫空间,这对我很好。这就是你为什么这么做的原因吗?这很有效。谢谢