如何禁用UIScrollView的水平滚动?


92

我有一个UIView像iPhone的Springboard。我已经使用UIScrollView和创建了它UIButtons。我想在所说的scrollview上禁用水平滚动。我只想要垂直滚动。我该如何完成?


5
您应该更改标题:在问题中要求水平,在标题中要求垂直。人们稍后会在搜索引擎上找到您的问题,所以两年后仍然很重要:)
Julien

@RahulVyas上面的人有一点。更改标题将减少通过搜索引擎到达这里的初学者的困惑(例如me;))。
SpacyRicochet 2011年

代表海报编辑了标题。(尽管当前正在等待同行评审,然后才能看到编辑内容。)
Duncan Babbage

Answers:


125

您必须设置的contentSize属性UIScrollView。例如,如果您UIScrollView的屏幕宽度为320像素(屏幕宽度),则可以执行以下操作:

CGSize scrollableSize = CGSizeMake(320, myScrollableHeight);
[myScrollView setContentSize:scrollableSize];

然后,UIScrollView它将仅垂直滚动,因为它已经可以水平显示所有内容。


6
你好 这个解决方案真的很好!感谢那。我尝试将静态宽度设置为0。我不知道以后是否可能会有一些副作用。但是,如果不知道大小(即iPhone和iPad的通用代码),那么效果很好!
JackPearse 2011年

5
我认为最好做CGSizeMake(0,myScrollableHeight),所以即使没有显示所有子视图,也禁止水平滚动。
LightNight

注意:使用分页时将尺寸之一设置为0会导致VoiceOver将页码宣布为“第1页,共1页”,而不考虑正确的值
josef 2014年

1
代替传递320硬编码的宽度,我们可以像传递:CGSize scrollableSize = CGSizeMake(self.scrollview.frame.size.width,myScrollableHeight); [myScrollView setContentSize:scrollableSize];
Mohit kumar

90

更新:在@EranMarom指出他的评论之后)

您可以在“ 方法”中停止水平滚动或垂直滚动ScrollViewDelegate。就是这样

停止水平滚动:

如果要水平滚动,则需要增加contentOffset.x。阻止滚动视图在水平方向上滚动。

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    sender.contentOffset.x = 0.0
}

停止垂直滚动:

如果要垂直滚动,则需要增加contentOffset.y。防止此操作停止scrollview沿垂直方向滚动。

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    sender.contentOffset.y = 0.0
}

上面的代码防止a 和中的更改,x并导致停止滚动方法。yscrollview contentOffsetscrollViewDidScroll:


1
我正在考虑投票,因为这个答案并不能说明您只是给出了代码本身就是这样。这样的回答不是很好。好的答案可以自我解释,而经验丰富的开发人员可能会理解这一点,而较新的开发人员可能不了解此处的情况。尚未被否决,因为它有改善的机会。
Popeye 2013年

13
这有点像破解,但是当其他所有方法都失败时,它就起作用了。因此+1,但只能作为不得已的手段。
i_am_jorf 2014年

5
我也使用了这种委托方法,但是我将主体替换为单线,例如:scrollView.contentOffset = CGPointMake(0, scrollView.contentOffset.y);禁用水平滚动。我发现它更具可读性,更小,并且没有必要进行零测试,因为很少有代码运行这种情况(例如,每秒最多几十次)几乎没有开销。
梯队2014年

因为您要在“ didscroll”之后更改contentOffset,而不像'willscroll'之前那样,并且这是一个锤子解决方案,但是我本人并没有投票,因为18票赞成,答案是75,所以不值得投票
LolaRun 2014年

2
在委托函数中,用于scrollView.contentOffset.y = 0.0停止垂直滚动和scrollView.contentOffset.x = 0.0停止水平滚动甚至更容易scrollViewDidScroll()。但是,我相信确保scrollView.contentSize均等scrollView.frame.size是更好(正确)的解决方案。参见@danbeaulieu答案。
EMEM

11

自iOS7使用以来

self.automaticallyAdjustsScrollViewInsets = NO;

//并创建包含3个页面的页面滚动器

    self.pageView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    [self.pageView setContentSize:CGSizeMake(self.view.frame.size.width*3, self.view.frame.size.height)];
    [self.pageView setShowsVerticalScrollIndicator:NO];
    [self.pageView setPagingEnabled:YES];
    [self.view addSubview:self.pageView];

我认为这不会禁用scrollview的滚动行为。是吗??
Dinesh Raja'2

self.collectionView.pagingEnabled = YES;帮助我解决了平滑滚动(不拖动)的问题。问题出在方法上scrollViewWillEndDragging:-targetContentOffset与scrollView.contentOffset相同,并且页面检测逻辑无法正常工作。
sig 2015年

11

快速解决方案

创建两个出口,一个用于视图,一个用于滚动视图:

@IBOutlet weak var myView: UIView!
@IBOutlet weak var scrollView: UIScrollView!

然后,您可以在viewDidLayoutSubviews中添加以下代码:

let scrollSize = CGSize(width: myView.frame.size.width, 
                        height: myView.frame.size.height)
scrollView.contentSize = scrollSize

我们所做的是收集视图的高度和宽度,并设置scrollViews内容大小以使其匹配。这将阻止滚动视图水平滚动。


更多想法:

CGSizeMake使用CGFloats来获取宽度和高度。您可能需要使用UIScrollViews的现有高度作为第二个参数。看起来像这样:

let scrollSize = CGSize(width: myView.frame.size.width, 
                        height: scrollView.contentSize.height)

如果您不知道高度或宽度(通用设备)怎么办?@danbeaulieu
Lukesivi '16

@lukesIvi“ myView.frame.width”正在动态地从“ myView” IBOutlet中拉出宽度。
Dan Beaulieu

4

就我而言,使用Swift 4.2可以使用:

禁用垂直滚动:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.y = 0.0
}

禁用水平滚动:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.x = 0.0
}

3

您可以选择视图,然后Attributes Inspector取消选中User Interaction Enabled


3

在我的情况下,contentView的宽度大于UIScrollView的宽度,这就是不必要的水平滚动的原因。我通过设置contentView的宽度等于UIScrollView的宽度来解决它。

希望对别人有帮助


@Nostradamus乐于提供帮助
Gulfam Khan,

0

我在viewDidLoad中设置了tableview contentInset(如下所示),这是什么导致水平滚动的

self.tableView.contentInset = UIEdgeInsetsMake(0, 30, 0, 0);

检查是否出于各种原因设置了tableview contentInset并将其禁用


0

我为此苦苦挣扎了一段时间,但未成功尝试此主题和其他主题中的各种建议。

但是,在另一个线程(不确定位置)中,有人建议在UIScrollView上使用负约束对他有效。

因此,我尝试了各种约束条件组合,但结果不一致。最终对我有用的是在滚动视图中添加-32的前后约束,并添加一个宽度为320(居中)的(不可见)文本视图。


0

试试这个:

CGSize scrollSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, scrollHeight);
[scrollView setContentSize: scrollSize];

0

通过覆盖contentOffset子类中的属性来禁用水平滚动。

override var contentOffset: CGPoint {
  get {
    return super.contentOffset
  }
  set {
    super.contentOffset = CGPoint(x: 0, y: newValue.y)
  }
}

0

iOS 11中引入的是的新属性 UIScrollView

var contentLayoutGuide: UILayoutGuide

该文档指出您:

当您要创建与滚动视图的内容区域相关的自动布局约束时,请使用此布局指南。

随着其它任何自动布局的限制,你可能会增加,你会想约束widthAnchor的的UIScrollViewcontentLayoutGuide是大小的‘帧’相同。您可以使用frameLayoutGuide(也在iOS 11中引入)或任何外部宽度(例如superView的)。

例:

NSLayoutConstraint.activate([
  scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: self.widthAnchor)
])

文档:https : //developer.apple.com/documentation/uikit/uiscrollview/2865870-contentlayoutguide



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.