为啥水平滚动视图内容之间存在差距?
Posted
技术标签:
【中文标题】为啥水平滚动视图内容之间存在差距?【英文标题】:Why is there a gap between horizontal scrollview content?为什么水平滚动视图内容之间存在差距? 【发布时间】:2015-07-27 15:54:49 【问题描述】:我设置了一个UIScrollView
,其中包含两个ViewController's
。这就是我的viewDidLoad
的样子:
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
scrollView.delegate = self
self.automaticallyAdjustsScrollViewInsets = false
let allViewController = self.storyboard!.instantiateViewControllerWithIdentifier("All") as! AllViewController;
let favoritesViewController = self.storyboard!.instantiateViewControllerWithIdentifier("Favorites") as! FavoritesViewController;
scrollView!.contentSize = CGSizeMake(2*CGRectGetWidth(allViewController.view.frame), CGRectGetHeight(scrollView!.frame));
let viewControllers = [allViewController, favoritesViewController]
var idx:Int = 0;
for viewController in viewControllers
addChildViewController(viewController);
let originX:CGFloat = CGFloat(idx) * CGRectGetWidth(scrollView!.frame);
viewController.view.frame = CGRectMake(originX, 0, viewController.view.frame.size.width, viewController.view.frame.size.height);
scrollView!.addSubview(viewController.view)
viewController.didMoveToParentViewController(self)
idx++;
在 iPhone 6 模拟器上一切正常,但是当我在 iPhone 5 模拟器上运行它时,滚动时控制器之间存在间隙:
[] scrollView 的前导、尾随、顶部和底部的自动布局设置为 0。
【问题讨论】:
【参考方案1】:如果您想在viewDidLoad:
中设置原点,并且您肯定知道滚动视图将具有屏幕宽度,请在计算逻辑中而不是CGRectGetWidth(scrollView!.frame)
使用
var bounds = UIScreen.mainScreen().bounds
var width = bounds.size.width
为了在您的子视图进行布局之前获得适当的宽度。
代码: Working Github Project
统一更新:
正如这里有人提到的,我取消选中滚动视图的Autoresize Subviews
属性,子类化UITableViewCell
并将我的提交推送到github。通过我上面提供的链接检查它。这是按钮向右对齐的结果:
结果:
参考: 主要概念在我的 SO 回答 here
中进行了描述【讨论】:
还是不行,现在间隙是一半大小,另一半出现在第二个视图控制器之后……所以绿色->白色(间隙)->紫色->白色跨度> 谢谢,它现在可以工作了。我会在 12 小时内将赏金奖励给你。我只有一个最后的问题。我的测试项目可以正常工作,但是在我的真实项目(实现 UITableViewDelegate、UITableViewDataSource 的 UIViewControllers)中有两个 tableview 而不是 viewcontroller,并且我在 UITableViewCell 的右侧有一个按钮,我也在那里进行了更改,但是我仍然看不到牢房的右侧,它在碎石的外面。有什么建议为什么会发生这种情况? @Adrian,可以在 3-4 小时内试用您的案例,并将发布更新的项目 @Adrian 请查看我的更新答案,请不要忘记奖励赏金 :) 顺便说一句,我看到您使用的是 4 英寸故事板....如果我在您的项目中使用 4.7 英寸故事板,那么我仍然有我的问题,没有看到右侧按钮。如果您有时间,您可以更新以使用 4.7 故事板吗?我会很感激的。【参考方案2】:您在视图中设置视图控制器位置确实加载。此时,视图的尺寸将与您的故事板中的视图大小相匹配。我假设您在情节提要中使用 4.7" 视图。这意味着在 viewDidLoad 中,您将第二个视图控制器的 x 位置设置为 375。在 viewWillAppear 或 didLayoutSubviews 中设置视图控制器位置以获得正确的宽度视图(iPhone 5 上为 320)。请注意,这两个方法都可以多次调用,因此请相应计划。
【讨论】:
我已经在 viewWillAppear 中设置了滚动视图的内容大小,但它的行为是一样的。是的,我正在使用 4.7 故事板viewWillAppear:
也太早了。您应该在viewDidLayoutSubviews
中设置框架,或者创建约束来布置它们。您可以在viewDidLoad
中创建约束。
即使在viewDidLayoutSubviews中,还是有差距的。我在情节提要中设置了约束
您在情节提要中设置了哪些约束?这些约束是否限制了在滚动视图中设置视图控制器的位置?
对于滚动视图 0 到顶部/底部/前导/尾随【参考方案3】:
如果您的子视图应始终为滚动视图的大小,最简单的解决方案可能是添加 UIScrollView 的自定义子类,该子类仅按添加顺序排列所有子视图,如下所示:
import UIKit
class MyScrollView: UIScrollView
override func layoutSubviews()
super.layoutSubviews()
var idx:Int = 0;
contentSize = CGSizeMake(2*CGRectGetWidth(bounds), CGRectGetHeight(bounds));
for sview in self.subviews as! [UIView]
let originX:CGFloat = CGFloat(idx) * CGRectGetWidth(bounds);
sview.frame = CGRectMake(originX, 0, CGRectGetWidth(bounds), CGRectGetHeight(bounds));
idx++
然后您可以将 viewDidLoad 简化为
override func viewDidLoad()
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
let allViewController = self.storyboard!.instantiateViewControllerWithIdentifier("All") as! AllViewController;
let favoritesViewController = self.storyboard!.instantiateViewControllerWithIdentifier("Favorites") as! FavoritesViewController;
for viewController in [allViewController, favoritesViewController]
addChildViewController(viewController);
scrollView!.addSubview(viewController.view)
viewController.didMoveToParentViewController(self)
【讨论】:
是的,这也一定需要。 更改了禁用子视图布局的建议,以在 UIScrollView 的自定义子类中手动布局子视图。将处理呼叫状态栏中的旋转和大小更改,ios 9 多任务处理中的大小更改等【参考方案4】:在你的滚动视图中添加两个子视图作为占位符,并在它们和滚动视图之间添加约束,并将两个@IBOutlet 设置为占位符。 在 viewDidLoad 中只需设置 scrollView 大小,添加 childViewControlers 并将其视图添加到占位符
【讨论】:
以上是关于为啥水平滚动视图内容之间存在差距?的主要内容,如果未能解决你的问题,请参考以下文章