Reputation: 20058
I have setup a UIScrollView
which contains two ViewController's
. This is how my viewDidLoad
looks like:
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++;
}
On the iPhone 6 simulator everything works ok, but when I run it on the iPhone 5 simulator there is gap between the controllers when scrolling:
[] The scrollView has auto layout set as 0 for leading, trailing, top and bottom.
Upvotes: 4
Views: 1134
Reputation: 5073
If you want to set the origins in viewDidLoad:
and you definitely know that your scroll view will have the width of your screen, in your calculation logic instead of CGRectGetWidth(scrollView!.frame)
use
var bounds = UIScreen.mainScreen().bounds
var width = bounds.size.width
in order to get proper width before your subviews did layout.
Code: Working Github Project
UPD:
As someone mentioned here, I unchecked scrollview's Autoresize Subviews
property, subclassed UITableViewCell
and pushed my commit to github. Check it through the link I provided above. Here you are the results with button aligned to the right:
Results:
Reference: The main concepts are described in my SO answer here
Upvotes: 2
Reputation: 1496
If your subviews should always be the size of the scroll view the simplest solution may be to add a custom subclass of UIScrollView that just layouts all subviews in the order they where added like so:
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++
}
}
}
You can then simplify viewDidLoad to
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)
}
}
Upvotes: 1
Reputation: 3641
Add two subviews in your scrollview as placeholders, and add constraints betwen them and scrollview, and make two @IBOutlet to placeholders.
In viewDidLoad just set scrollView size, add childViewControlers and their views add to placeholders
Upvotes: 0
Reputation: 4446
You're setting the view controller positions in view did load. At that point, the views will have the dimensions matching the size of the views from your storyboard. I'm assuming you're using 4.7" views in your storyboards. This means that in viewDidLoad, you're setting the second view controller's x position to 375. Set the view controller position in viewWillAppear or didLayoutSubviews to get the correct width of the view (320 on iPhone 5). Note, both of those methods can be called more than once so plan accordingly.
Upvotes: 1