我是Swift的新手,我尝试制作显示视图控制器的UIScrollView
。
在iPhone 11 Pro Max上,一切都很完美,下一屏在侧面显示了一点:
the orange strip is the next screen
我的代码:
//MARK: - outlets
@IBOutlet weak var pageControl: UIPageControl!
@IBOutlet weak var scrollView: UIScrollView!
//MARK: - properties
var viewControllers: [String] = ["ComputerViewController", "AttactViewController", "DefenceViewController", "OfflineViewController"]
var frame = CGRect(x: 0, y: 0, width: 0, height: 0)
//MARK: - life cyrcles
override func viewDidLoad() {
super.viewDidLoad()
for index in 0..<viewControllers.count {
frame.origin.x = scrollView.frame.size.width * CGFloat(index)
frame.size = scrollView.frame.size
let view = UIView(frame: frame)
let storyboard = UIStoryboard(name: "Menu", bundle: nil)
var controller: UIViewController = storyboard.instantiateViewController(withIdentifier: viewControllers[index]) as UIViewController
view.addSubview(controller.view)
self.scrollView.addSubview(view)
}
scrollView.contentSize = CGSize(width: scrollView.frame.size.width * CGFloat(viewControllers.count), height: scrollView.frame.size.height)
scrollView.delegate = self
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
var pageNumber = scrollView.contentOffset.x / scrollView.frame.size.width
pageControl.currentPage = Int(pageNumber)
}
感谢您的帮助...
一些观察:
您应避免引用frame
中的viewDidLoad
。此时,frame
未知。
您应该完全避免对子视图的大小和位置进行硬编码。以后可能会有多种事件改变视图的大小(例如,旋转,拆分视图多任务处理等)。使用约束。
具有滚动视图,有两个布局指南,一个用于frame
,另一个用于contentSize
。因此,请使用frameLayoutGuide
设置子视图的大小以及这些子视图相对于contentLayoutGuide
的位置。
将视图控制器的view
添加为子视图时,请确保调用addChild(_:)
和didMove(toParent:)
调用以包含视图控制器。请参见view controller documentation的“实现容器视图控制器”部分。
如果要添加分页行为,只需设置滚动视图的isPagingEnabled
。
将它们全部拉在一起:
override func viewDidLoad() {
super.viewDidLoad()
addChildViews()
}
override func viewDidLoad() {
super.viewDidLoad()
var anchor = scrollView.contentLayoutGuide.leadingAnchor
for identifier in viewControllers {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let child = storyboard.instantiateViewController(withIdentifier: identifier)
addChild(child) // containment call
child.view.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(child.view)
child.didMove(toParent: self) // containment call
NSLayoutConstraint.activate([
// define size of child view (relative to `frameLayoutGuide`)
child.view.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor),
child.view.heightAnchor.constraint(equalTo: scrollView.frameLayoutGuide.heightAnchor),
// define placement of child view (relative to `contentLayoutGuide`)
child.view.leadingAnchor.constraint(equalTo: anchor),
child.view.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
child.view.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
])
anchor = child.view.trailingAnchor
}
anchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor).isActive = true
scrollView.isPagingEnabled = true
}
我已删除frame
属性,因为不再需要该属性(这只是与视图控制器的同名视图属性相混淆的原因)。我还取消了容器视图,因为它并没有对整个解决方案增加太多(并且只添加了一层约束)。
但是关键是使用约束来指示滚动视图内子视图的大小和位置,并使用视图控制器包含API。