I am making an universal demo xcode project which is a UIScrollView
contains two pages, scroll left and right to go back and forth.
My questions is iPad and iPhone's layout is not the same.
ViewController
has the UIScrollView
.
AViewController
contains an UILabel
in the center("Good morning...
").
BViewController
contains an UILabel
in the center("Good night...
").
Here is the code of ViewController
:
class ViewController: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
let story = UIStoryboard(name: "Main", bundle: nil)
let vc1 = story.instantiateViewController(withIdentifier: "AViewController")
let vc2 = story.instantiateViewController(withIdentifier: "BViewController")
vc1.view.backgroundColor = UIColor.green
vc2.view.backgroundColor = UIColor.red
addContentView([vc1, vc2])
scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width * 2, height: scrollView.frame.height)
}
func addContentView(_ viewControllers: [UIViewController]) {
viewControllers.enumerated().forEach {
addChildViewController($1)
$1.view.frame = CGRect(x: UIScreen.main.bounds.width * CGFloat($0), y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
scrollView.addSubview($1.view)
didMove(toParentViewController: $1)
}
}
}
If I choose View as iPhone 8 then the layout works correct in iPhone 8 like this: (Swipe then from green to red)
But for iPad:
The labels are not centered!!.
If I choose View as iPad ... ,then for iPhone it doesn't layout correct.
Here is the view hierarchy, it's obvious the layout is correct but for some reason the green view is larger than screen size and covered by the red one.
Thanks for any help.
The code is here: https://github.com/williamhqs/TestLayout
The embedded view controller views have translatesAutoresizingMaskIntoConstraints = true
by default which introduces bogus constraints:
Setting it to false will not let you just set the frame manually, so you will have to write the full layout. It's slightly more verbose, but autolayout will work for the embedded view controllers and you get rotation support as well:
@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
let story = UIStoryboard(name: "Main", bundle: nil)
let vc1 = story.instantiateViewController(withIdentifier: "AViewController")
let vc2 = story.instantiateViewController(withIdentifier: "BViewController")
vc1.view.backgroundColor = UIColor.green
vc2.view.backgroundColor = UIColor.red
addContentView([vc1, vc2])
}
func addContentView(_ viewControllers: [UIViewController]) {
var previousController: UIViewController? = nil
viewControllers.forEach {
addChildViewController($0)
$0.view.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview($0.view)
$0.view.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
$0.view.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
if let trailing = previousController?.view.trailingAnchor {
$0.view.leadingAnchor.constraint(equalTo: trailing).isActive = true
} else {
$0.view.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
}
$0.view.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
$0.view.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
didMove(toParentViewController: self)
previousController = $0
}
previousController?.view.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
}
Scroll view works as expected for all devices, regardless of the Xcode View as setting: