[英]Cannot add any subview to scrollView
我感到很困惑。 我無法讓任何子視圖出現在滾動視圖中
具體來說,我想添加另一個視圖控制器的視圖,但我什至無法添加任何標簽或任何東西。 我也看不到視圖調試器層次結構中的任何子視圖
我究竟做錯了什么??
import UIKit
class MainViewController: UIViewController {
var scrollView: UIScrollView {
let scrollView = UIScrollView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
scrollView.isPagingEnabled = true
scrollView.backgroundColor = .orange
scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width * 3.0, height: UIScreen.main.bounds.height)
return scrollView
}
var leftViewController: UIViewController {
let vC = UIViewController()
vC.view.backgroundColor = .purple
return vC
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
leftViewController.view.frame = .init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
addChild(leftViewController)
scrollView.addSubview(leftViewController.view)
leftViewController.didMove(toParent: self)
}
}
可以通過自動布局實現我想要的效果,但仍然是硬編碼寬度。
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
scrollView.addSubview(scrollViewContainer)
scrollViewContainer.addArrangedSubview(redView)
scrollViewContainer.addArrangedSubview(blueView)
scrollViewContainer.addArrangedSubview(greenView)
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
scrollViewContainer.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
scrollViewContainer.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
scrollViewContainer.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
scrollViewContainer.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
}
let scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.isPagingEnabled = true
scrollView.translatesAutoresizingMaskIntoConstraints = false
return scrollView
}()
let scrollViewContainer: UIStackView = {
let view = UIStackView()
view.axis = .horizontal
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let redView: UIView = {
let view = UIView()
view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height).isActive = true
view.backgroundColor = .red
return view
}()
let blueView: UIView = {
let view = UIView()
view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height).isActive = true
view.backgroundColor = .blue
return view
}()
let greenView: UIView = {
let view = UIView()
view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height).isActive = true
view.backgroundColor = .green
return view
}()
}
如果不出意外,如果您在原始問題中提供了第一個示例,那么您正在使用計算屬性。 每次引用它們時,它們都會返回一個新實例。 您應該創建這些存儲屬性:
var scrollView: UIScrollView = {
let scrollView = UIScrollView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
scrollView.isPagingEnabled = true
scrollView.backgroundColor = .orange
scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width * 3.0, height: UIScreen.main.bounds.height)
return scrollView
}()
var leftViewController: UIViewController = {
let vC = UIViewController()
vC.view.backgroundColor = .purple
return vC
}()
請注意=
並在末尾添加()
以指定它們已使用閉包進行初始化。
計算屬性的問題在於,由於每個引用都返回一個新實例,因此您調整其frame
的子視圖控制器的視圖與您添加為子視圖的視圖不同。 並且您添加子項的滾動視圖與您添加到容器視圖控制器的滾動視圖不同。
在您修改后的問題中,您使用約束共享了代碼。 如果使用約束,請確保將所有相關視圖的translatesAutoresizingMaskIntoConstraints
設置為false
。 否則,它會自動將視圖的自動調整大小掩碼轉換為與您手動添加的新約束沖突的約束。
並且您還應該避免使用constraint(equalToConstant:)
,使用constraint(equalTo:)
,盡可能引用主視圖。 例如:
class ViewController: UIViewController {
let scrollView: UIScrollView = {
let view = UIScrollView()
view.translatesAutoresizingMaskIntoConstraints = false
view.isPagingEnabled = true
return view
}()
let redView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .red
return view
}()
let greenView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .green
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
scrollView.addSubview(redView)
scrollView.addSubview(greenView)
NSLayoutConstraint.activate([
// set the scroll view to be the size of the main view
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
// set the subviews to be the size of the main view, too
redView.widthAnchor.constraint(equalTo: view.widthAnchor),
redView.heightAnchor.constraint(equalTo: view.heightAnchor),
greenView.widthAnchor.constraint(equalTo: view.widthAnchor),
greenView.heightAnchor.constraint(equalTo: view.heightAnchor),
// now dictate where these subviews are in the scroll view vertically ...
redView.topAnchor.constraint(equalTo: scrollView.topAnchor),
greenView.topAnchor.constraint(equalTo: scrollView.topAnchor),
redView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
greenView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
// ... and horizontally
redView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
greenView.leadingAnchor.constraint(equalTo: redView.trailingAnchor),
greenView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor)
])
}
}
坦率地說,既然你在談論全屏子視圖控制器,我會完全放棄這段代碼,只使用UIPageViewController
(這不僅讓我們擺脫了調整子視圖控制器頂級視圖大小的業務,而且讓我們做一個更有效的“及時”創建子視圖控制器)。
但我想展示如果您手動執行此操作,約束會是什么樣子。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.