如何保持 UIScrollView 内容大小的最小高度?

Posted

技术标签:

【中文标题】如何保持 UIScrollView 内容大小的最小高度?【英文标题】:How to maintain a minimum height of content size of UIScrollView? 【发布时间】:2015-02-11 11:21:38 【问题描述】:

我有一个 UIScrollView A(实际上是一个 UICollectionView)填充 UINavigationController B 内的屏幕。控制器 B 的 adjustScrollViewInsets 设置为 true。

我想在用户向上滚动时隐藏导航栏,并在向下滚动时显示它。以下是我的代码:

func scrollViewDidScroll(scrollView: UIScrollView) 
    if (self.lastContentOffset < scrollView.contentSize.height - scrollView.frame.size.height && self.lastContentOffset > scrollView.contentOffset.y) 
        //  dragging down
        if self.navigationController!.navigationBarHidden 
            self.navigationController?.setNavigationBarHidden(false, animated: true)
        
     else if (self.lastContentOffset > 0 && self.lastContentOffset < scrollView.contentOffset.y) 
        //  dragging up
        if !self.navigationController!.navigationBarHidden 
            self.navigationController?.setNavigationBarHidden(true, animated: true)
        
    

    self.lastContentOffset = scrollView.contentOffset.y

现在的问题是,由于 iPhone 6+ 的屏幕太大,当导航栏被隐藏时,滚动视图 A 的 contentSize 小于它的框架(即全屏框架)。在这种情况下,滚动视图将无法滚动,导航栏将永远不会再返回。

我想手动将 A 的 contentSize 的高度保持为屏幕至少 height + 1,但不知道该怎么做。有人可以帮忙吗?或者提供更好的解决方案?

顺便说一句,我使用的是 ios 8 和 Swift。

【问题讨论】:

【参考方案1】:

假设您需要将滚动视图的最小内容大小保持为 100(当然这将是动态的,并且会因设备而异)

NSInteger minScrollViewContentHeight = 100;

用内容填充滚动视图后,您需要检查滚动视图的内容大小是否小于所需的最小滚动视图内容大小。如果它小于所需的内容大小,则需要设置滚动视图的最小内容大小,如下所示 -

if(scrollView.contentSize.height < minScrollViewContentHeight)
    [scrollView setContentSize:CGSizeMake(scrollView.frame.size.width, minScrollViewContentHeight)];

【讨论】:

【参考方案2】:

在我的脑海中(我正在打电话),我认为 contentSize 不是只读的。

如何根据滚动方向等情况手动将其更改为所需的数量?

类似:

如果导航栏被隐藏则 contentSize = 不管

【讨论】:

【参考方案3】:

一个选项是使用单元格的出现和消失来触发显示/隐藏。

使用委托方法collectionView:willDisplayCell:forItemAtIndexPath:collectionView:didEndDisplayingCell:forItemAtIndexPath: 来检测运动。您可以从正在显示或删除的单元格的索引更改中计算出方向。如果您无法滚动屏幕,则不会发生任何事情。

【讨论】:

【参考方案4】:

您不必更改偏移量(实际上只是滚动位置),而是更改 contentSize 本身。这意味着,当您隐藏导航栏时,通过导航高度增加 contentSize(不要记住数字),当您显示导航栏时,减少 contentSize。或者... 在显示/隐藏导航栏后使用 AutoLayout 和 layoutIfNeeded 方法。

【讨论】:

【参考方案5】:

我偶然发现了一个类似的问题。我需要一个最小的可滚动区域来用于我正在使用的 tableview。

ScrollView 可能会更容易一些,因为您可以直接修改 contentView 的大小。 如果您使用的是 autoLayout,请尝试在 contentView 和 scrollView 本身之间添加等高约束。 contentView.height = scrollView.height + scrollMin;

对于我的 tableView,我必须继承 UITableView 并覆盖 contentSize 设置器。

#define MIN_SCROLL 60

- (void)setContentSize:(CGSize)contentSize 
  //take insets into account
  UIEdgeInsets insets = self.contentInset;
  CGFloat minHeight = self.frame.size.height - insets.top - insets.bottom + MIN_SCROLL;
  if(contentSize.height < minHeight) 
    contentSize.height = minHeight;
  
  [super setContentSize:contentSize];

【讨论】:

以上是关于如何保持 UIScrollView 内容大小的最小高度?的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 更改 UIScrollView 的大小后 ContentOffset 保持不变

保持 UIScrollView 滚动到底部

在 UIScrollView 中自动调整 UITextView 的大小

如何动态调整 UIScrollView 的大小?

如何调整 UIScrollView 的大小以适合子 UITextViews 的内容

UIScrollView 需要根据 UILabel 大小进行扩展但保持底部标签栏