ios - 无法将任何子视图添加到 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
(这不仅让我们摆脱了调整子视图控制器顶级视图大小的业务,而且让我们做一个更有效的“及时”创建子视图控制器)。
但我想展示如果您手动执行此操作,约束会是什么样子。
推荐阅读
- android - 程序类型已经存在:okhttp3.Call$Factory
- mongodb - 尝试连接到 mongodb 容器时,GOLANG 客户端 docker 容器无法访问
- c++ - 在编译时使用带有参数类型检查的可变参数模板在 C++ 中获取函数的参数数量
- sql-server - 如何:UDF 函数提取子字符串?
- php - imagecreatefromjpeg($file_name): 无法打开流
- sql - sql中的日期时间过滤器
- php - 如何在html水平表中制作数组,每个数组分为2列
- ios - Swift 4:使用调用的 C++ 桥接函数杀死正在执行的线程
- javascript - 回调中设置的 Redux 存储值
- python - 在课堂上使用多处理模块