Swift UIScrollView – 仅针对垂直滚动的正确实现

事先,我道歉,因为我会说我是iOS编程的初学者。

我想使用UIScrollView因为要显示的内容超出了屏幕的高度。 因此,我只想垂直滚动而不是水平滚动。

我正在使用Storyboard通过AutoLayout绘制视图。

以下是带有UIScrollView UIViewController的屏幕截图:

在此处输入图像描述在此处输入图像描述

然后我将Label更改为这样的大文本

 override func viewDidLoad() { super.viewDidLoad() self.label1Label.text = "Seize jours après la chute du président Blaise Compaoré, le Burkina Faso a un nouveau chef d'EtatA l'issue d'ultimes tractions, civils et militaires se sont accordés, lundi 17 novembre, sur le nom du diplomate Michel KafandoSeize jours après la chute du président Blaise Compaoré, le Burkina Faso a un nouveau chef d'EtatA l'issue d'ultimes tractions, civils et militaires se sont accordés, lundi 17 novembre, sur le nom du diplomate Michel Kafando" self.label1Label.numberOfLines = 0 self.label1Label.sizeToFit() 

我的问题是,如果我没有手动设置我的contentView的宽度(在UIScrollView ),滚动是水平的,而不是垂直的。 (看下面的截图):

在此处输入图像描述

我已经尝试设置contentSize,就像我在许多谷歌post中看到的那样但没有成功:

 self.scrollView.contentSize = CGSizeMake(400.0, 600.0) 

如果我为我的内容视图手动设置宽度( ie : 320pts ),则滚动将是垂直的(GOOD),但是根据iphone的大小,它将不会覆盖整个屏幕宽度,如下面的屏幕截图所示:

在此处输入图像描述

问题是:使用UIScrollView一个尊重autolayout约束的contentViewfull screen : 0top - 0bottom - 0left - 0right )和滚动只是垂直的正确实现是什么。

非常感谢你的帮助!

Mike Woelmer演示了如何在Atomic Object博客上使用Interface Builder正确执行此操作。

http://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/

我在github上也只有自己的代码(没有故事板实现)。

https://github.com/nadthevlad/AutolayotScrollview

您不希望设置内容或视图的高度或宽度。 相反,您希望使用Autolayouts引脚和约束来设置scrollview的行为方式。

  1. 创建您的UIScrollView * scrollView。

  2. 您想要创建一个UIView * contentView,您将其余的视图元素放入其中。

     [self.view addSubview:scrollView]; [scrollView addSubview:contentView]; [contentView addSubview:_label1]; [contentView addSubview:_label2]; [contentView addSubview:_label3]; [contentView addSubview:_label4]; [contentView addSubview:_label5]; [contentView addSubview:_label6]; 
  3. 将scrollView的4个边缘固定到self.view的4个边缘

  4. 将contentView的顶部和底部边缘固定到scrollView的顶部和底部。

  5. 这是棘手的部分。 要设置水平大小调整,您希望将contentView的前(右)和后(左)边固定到前端和后端self.view而不是scrollView。 尽管contenView是scrollView的子视图,但它的水平约束将到达scrollView之外并连接到self.view。

  6. 像往常一样将任何其他视图元素固定到contentView。

允许UIScrollView仅向一个方向滚动的技巧是使受限维度的UIScrollView的内容大小与同一维度中UIScrollView框架的大小相同。 所以在这种情况下, scrollview.contentSize.width应该等于scrollview.frame.size.width

考虑到这一点,请尝试以下方法:

  1. 确保以与本答案中描述的相同方式设置约束

  2. 将以下代码添加到视图控制器:

     override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews(); self.scrollView.contentSize.height = 3000; // Or whatever you want it to be. } 

就个人而言,我真的不喜欢Auto Layout。 如果你有兴趣尝试没有自动布局 – 即。 只需使用代码而不是约束 – 您可以关闭视图控制器视图的自动布局,并将viewWillLayoutSubviews方法更改为如下所示:

 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews(); self.scrollView.frame = self.view.bounds; // Instead of using auto layout self.scrollView.contentSize.height = 3000; // Or whatever you want it to be. } 

这就是我总是通过约束从故事板垂直滚动的方法:

1拖动一个viewcontroller

2在控制器的主视图中拖动一个滚动视图,其中约束L = 0,T = 0,T = 0和B = 0到其超视图(控制器的主视图)。

3将UIVIew拖动到滚动视图中作为其内容视图,其约束L-0,T = 0,T = 0,B = 0到其superview(scrollview)

  • 这里是时候设置滚动视图的内容大小,它控制水平和垂直滚动,如下所示。

4 – 用于停止水平滚动,使内容视图的宽度等于具有约束的scrollview。

5-make内容视图的高度等于控制器视图的高度,这是临时的, 直到我们用可滚动的内容填充它

6在内容视图中添加控件直到完成。

7 – 并且最重要的是删除您在内容视图的高度的第5点中所做的约束,而不是从内容视图底部的控件进行约束以使其与底部对齐。 这有助于使内容视图从第一次控制开始上下,直到最后一次控制(这完全取决于此步骤)。

8-刚刚运行,结果应该符合预期,否则请告诉我。

希望这可以帮助!

我只将这个实现用于水平/垂直滚动视图,虽然它在Objective-C中,但如果你不清楚,我会尝试解释逻辑。

 //Getting iDevice's screen width CGRect screenRect = [[UIScreen mainScreen] bounds]; CGFloat screenWidth = screenRect.size.width; //Setting the right content size - only height is being calculated depenging on content. CGSize contentSize = CGSizeMake(screenWidth, HEIGHT_OF_YOUR_CONTENT); self.scrollView.contentSize = contentSize; 

现在,scrollview的contentSize属性的宽度将附加到设备屏幕的实际宽度,因此scrollview将仅在垂直方向上滚动。

感谢@NadtheVlad,我终于看到了光明。 一些进一步的小提示告诉我,contentView只需要固定到scrollView的顶部,底部和宽度。 无需参考self.view。

使用EasyPeasy ,这很简单:

 scrollView <- Edges() contentView <- [Top(), Bottom(), Width().like(scrollView)]