我有一个 UIScrollView
,其中包含许多 UIImageView
、UILabels 等...标签比 UIScrollView
长得多,但是当我运行应用程序时,我无法单击并向下滚动...
为什么会这样?
谢谢
展示一个完整的工作代码片段总是好的:
// in viewDidLoad (if using Autolayout check note below):
UIScrollView *myScrollView;
UIView *contentView;
// scrollview won't scroll unless content size explicitly set
[myScrollView addSubview:contentView];//if the contentView is not already inside your scrollview in your xib/StoryBoard doc
myScrollView.contentSize = contentView.frame.size; //sets ScrollView content size
斯威夫特 4.0
let myScrollView
let contentView
// scrollview won't scroll unless content size explicitly set
myScrollView.addSubview(contentView)//if the contentView is not already inside your scrollview in your xib/StoryBoard doc
myScrollView.contentSize = contentView.frame.size //sets ScrollView content size
我还没有找到在 IB 中设置 contentSize 的方法(从 Xcode 5.0 开始)。
注意:如果您使用 Autolayout,放置此代码的最佳位置是在 -(void)viewDidLayoutSubviews
方法内。
如果在正确设置 contentSize 后仍无法滚动视图,请确保取消选中 Interface Builder -> File Inspector 中的“使用 AutoLayout”。
您需要设置滚动视图的 contentSize
属性才能使其正确滚动。
如果您使用自动布局,则需要在 viewDidLayoutSubviews
中设置 contentSize
以便在自动布局完成后应用它。
代码可能如下所示:
-(void)viewDidLayoutSubviews
{
// The scrollview needs to know the content size for it to work correctly
self.scrollView.contentSize = CGSizeMake(
self.scrollContent.frame.size.width,
self.scrollContent.frame.size.height + 300
);
}
contentSize
的值设置为 contentView
的大小,scrollView 和 contentView 的大小似乎也设置为相同。但是将 contentSize
的高度设置为大于 contentView
的高度的值,它起作用了。
viewDidLayoutSubviews
在生命周期中可能会被多次调用,因此您冒着增加高度超出预期的风险。
上面的答案是正确的 - 要进行滚动,有必要设置内容大小。
如果您正在使用界面构建器,那么一种巧妙的方法是使用用户定义的运行时属性。例如:
https://i.stack.imgur.com/EFkqw.png
尝试将内容大小调整为巨大的数字。我不明白为什么我的滚动视图不滚动,即使它的内容大小似乎大于控件大小。我发现如果内容大小小于需要,它也不起作用。
self.scrollView.contentSize = CGSizeMake(2000, 2000);
您可以输入自己的大数字,而不是 2000。如果它有效,则意味着调整大小时您的内容大小不够大。
委托不是滚动视图工作所必需的。
确保您将滚动视图的 contentSize 属性设置为正确的大小(即,一个大到足以包含所有内容的大小。)
取消选中“使用自动布局”对我有用。
环境:xCode 5.0.2 Storyboards ios7
在我的情况下,我必须将 delaysContentTouches
设置为 true,因为 scrollView 内的对象都在捕获触摸事件并自行处理,而不是让 scrollView 自己处理它。
在 ViewDidLayoutSubviews
方法中设置 UIScrollview
的 contentSize
属性。像这样的东西
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = CGSizeMake(view.frame.size.width, view.frame.size.height)
}
为什么滚动视图不滚动的想法是因为您将滚动的内容大小设置为小于滚动视图的大小,这是错误的。您应该将内容大小设置为大于滚动视图的大小,以便在滚动时浏览它。
与缩放相同的想法,您设置缩放的最小值和最大值,这将通过缩放动作应用。
欢迎 :)
一个小的补充,以上都是你的滚动视图可能不滚动的实际原因,但有时这可能是通过代码而不是 IB 添加滚动视图时的原因,你可能已经将子视图添加到父视图而不是滚动视图这会导致子视图不滚动
并保持内容大小设置并大于父视图框架(duhh !!)
我在第一次尝试时就成功了。有了自动布局和一切,没有额外的代码。然后一个集合视图变得香蕉,在运行时崩溃,我找不到问题所在,所以我删除并重新创建了它(我使用的是 Xcode 10 Beta 4。感觉就像一个错误)然后滚动消失了。但是,集合视图再次起作用了!
几个小时后..这就是为我解决的问题。我有以下布局:
界面视图
安全区
滚动视图 内容视图
内容视图
这一切都在约束中。安全区域由系统自动定义。在最坏的情况下,删除滚动和内容视图的所有约束,并且没有 IB 为您重置/创建它们。手动制作它们,它可以工作。
对于滚动视图,我做了:将尾随/顶部对齐到安全区域。与安全区域相等的宽度/高度。
对于内容视图,我做了:将尾随/前导/顶部/底部与 Superview 对齐(滚动视图)
基本上这个概念是让内容视图适合滚动视图,它适合安全区域。
但它没有工作。内容视图错过了高度。我尽我所能,唯一能做到的就是创建一个内容视图高度,控制拖动内容视图..到它自己。这定义了一个固定的高度,该值是从视图控制器的大小(定义为自由形式,比实际显示长,包含我所有的子视图)计算出来的,最后它再次工作!
如果您收到 viewDidLayoutSubviews
不存在的消息(IOS8 / swift),请改用以下内容
override func viewDidAppear(animated: Bool)
这为我解决了
我的问题通过以下方式解决:
将scrollView上的contentSize设置为很大的高度但我还必须修复scrollView中视图的顶部和/或底部约束,这意味着滚动指示器显示在屏幕上但内容没有滚动
一旦我删除了绑定到安全区域和/或超级视图的顶部和/或底部约束,scrollView 内的视图可以再次滚动并且不会固定在屏幕底部的顶部!
希望这可以阻止其他人因这个特定问题而遭受数小时的痛苦。
另一个有趣的案例:
scrollview.superview.userInteractionEnabled 必须为 true
我浪费了 2 个小时以上的时间来追查这个只是为了弄清楚父级是 UIImageView,它自然地具有 userInteractionEnabled == false
之前没有提到的东西!
确保您的插座正确连接到滚动视图!它应该有一个实心圆圈,但即使你有一个实心圆圈,scrollView 也可能没有连接 - 所以请仔细检查!将鼠标悬停在圆圈上,看看实际的滚动视图是否突出显示! (这对我来说是一个案例)
//Connect below well to the scrollView in the storyBoard
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
如果您遵循教程,很多时候代码是正确的,但许多初学者不知道的是,scrollView 不会在模拟器中正常滚动。假设只有当您按下鼠标垫并同时滚动时才会滚动。许多有经验的 XCode/Swift/Obj-C 用户非常习惯这样做,所以他们不知道初学者怎么可能忽略它。再见 :-)
@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
// Do any additional setup after the view
}
override func viewWillLayoutSubviews(){
super.viewWillLayoutSubviews()
scrollView.contentSize = CGSize(width: 375, height: 800)
}
只要你按照我上面所说的去做,这段代码就可以很好地工作
添加 UIScrollViewDelegate
并将以下代码添加到 viewDidAppear
方法为我修复了它。
@interface testScrollViewController () <UIScrollViewDelegate>
-(void)viewDidAppear:(BOOL)animated {
self.scrollView.delegate = self;
self.scrollView.scrollEnabled = YES;
self.scrollView.contentSize = CGSizeMake(375, 800);
}
如果其他解决方案都不适合您,请仔细检查您的滚动视图是否确实是 Interface Builder 中的 UIScrollView
。
在过去几天的某个时间点,我的 UIScrollView
自发更改类型 为 UIView
,尽管它的类在检查器中显示为 UIScrollView
。我正在使用 Xcode 5.1 (5B130a)
。
您可以创建新的滚动视图并从旧视图复制测量值、设置和约束,也可以手动将视图更改为 xib
文件中的 UIScrollView
。我做了一个比较,发现以下差异:
原来的:
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" directionalLockEnabled="YES" bounces="NO" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wsk-WB-LMH">
...
</scrollView>
类型自发改变后:
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" customClass="UIScrollView" id="qRn-TP-cXd">
...
</view>
所以我用原来的 <scrollView>
行替换了 <view>
行。
我还将视图的结束标记 </view>
替换为 </scrollView>
。
请务必保持 id 与当前视图相同,在本例中为:id="qRn-TP-cXd"。
我还必须通过删除应用程序的派生数据来从 Xcode 的缓存中刷新 xib:
Xcode->Window->Organizer->Projects,选择你的项目,在 Derived Data 行,点击 Delete...
或者,如果使用设备:
Xcode->Window->Organizer->Device,选择你的设备->Applications,选择你的应用,点击(-)
现在清理项目,并从模拟器/设备中删除应用程序:
Xcode->产品->清理
iOS模拟器/设备->按住app->点击(X)将其移除
然后,您应该能够构建和运行您的应用程序并再次具有滚动功能。
PS 我不必在 viewDidLayoutSubviews
中设置滚动视图的内容大小或关闭自动布局,而是 YMMV。
如果您的 scrollView
是某种类型的 containerView
的子视图,请确保您的 scrollView
在 containerView
的框架或边界内。我有 containerView.clipsToBounds = NO
,它仍然允许我看到滚动视图,但因为 scrollView
不在 containerView
的范围内,它不会检测到触摸事件。
例如:
containerView.frame = CGRectMake(0, 0, 200, 200);
scrollView.frame = CGRectMake(0, 200, 200, 200);
[containerView addSubview:scrollView];
scrollView.userInteractionEnabled = YES;
您将能够看到 scrollView 但它不会接收用户交互。
在 viewDidLayoutSubviews
中添加以下代码对我来说适用于自动布局。尝试所有答案后:
- (void)viewDidLayoutSubviews
{
self.activationScrollView.contentSize = CGSizeMake(IPHONE_SCREEN_WIDTH, 620);
}
//set the height of content size as required
直接的编程方式
把它包起来
创建一个 UIScrollView
private lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
return scrollView
}()
使用单个子视图来保存所有内容子视图
private lazy var contentView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
添加您的观点
contentView.addSubview(firstSubView)
contentView.addSubview(lastSubView)
scrollView.addSubview(contentView)
view.addSubview(scrollView)
通常,您只希望您的内容向一个方向滚动。在大多数情况下垂直滚动。因此将内容视图的宽度设置为滚动视图的宽度。
NSLayoutConstraint.activate([
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
将四个约束(上、下、左、右)从我们的单个内容视图附加到滚动视图。
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
确保您在内容视图的所有四个侧面都附加了约束,以便它将扩展到您的内容的大小。
// After Adding your subviews to the contentView make sure you've those two constraints set:
firstSubView.topAnchor.constraint(equalTo: contentView.topAnchor),
.
.
.
lastSubView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])
参考:Using UIScrollView with Auto Layout in iOS
在此线程中提供的答案失败后,我偶然发现了 this article 的解决方案。
使用自动布局设置滚动视图有两点不直观:
您在 contentview 和 scrollview 之间设置为边距的约束不会影响 contentview 的大小。他们真的是利润。为了让它工作,内容视图应该有一个固定的大小。固定大小的诀窍是您可以将内容视图的宽度设置为等于滚动视图父级的宽度。只需选择左侧树中的两个视图并添加等宽约束。
这是那篇文章的要点。如需完整的解释,包括插图,请查看。
我发现这个 AutoLayout 问题...如果我只是让 ViewController
使用 UIView
而不是 UIScrollView
作为类...然后只需添加一个 UIScrollView
我自己...它可以工作。
我在 IB 遇到了同样的问题。
将 scrollView 的前导、尾随、顶部和底部设置为其 superView 之后。我进行了以下更改以使 containerView 可滚动,这很有效。
要使 scrollView 仅在水平方向上滚动,请使用 scrollView 的 centerY = ContainerView 的 centerY 进行约束
并使其垂直滚动,使 scrollView 的 centerX = ContainerView 的 centerX
如果有人像我一样犯了同样的错误,我想分享我的情况。
在我的情况下,我错误地向 scrollview 的一个子视图添加了一个约束,这使得子视图的空间到 topLayoutGuide 是固定的,因此它的位置不能改变,所以不能滚动滚动视图。
不定期副业成功案例分享
myScrollView.delegate = self
ALSO,如果这仍然不起作用,下面的答案有很好的建议(转到您的 xib/StoryBoard 并确保禁用“自动布局”)。专业提示:如果您希望以编程方式滚动 UIScrollView 等操作,还可以在 .h 文件中包含<UIScrollViewDelegate>
。viewDidLayoutSubviews
使它对我有用。