ios - Swift - 自动布局约束 UIView-Encapsulated-Layout-Width
问题描述
我正在尝试以编程方式执行 UI,但遇到了奇怪的约束错误,但是当我运行应用程序时,它看起来符合预期。
我正在尝试做的事情:
我有一个 ViewControllerTodayVC
我有一个UIView
并且我正在尝试MWStepsActivityVC
在该视图中呈现内容。
这是我的 TodayVC:
class TodayVC: UIViewController {
let scrollView = UIScrollView()
let contentView = UIView()
let stepsActivityView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
configureViewController()
configureScrollView()
configureContainerViews()
layoutUI()
}
func configureViewController() {
view.backgroundColor = .systemBackground
}
func configureScrollView() {
view.addSubview(scrollView)
scrollView.addSubview(contentView)
scrollView.pinToEdges(of: view)
contentView.pinToEdges(of: scrollView)
NSLayoutConstraint.activate([
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
contentView.heightAnchor.constraint(equalToConstant: 600)
])
}
func configureContainerViews() {
self.add(childVC: MWStepsActivityVC(activityType: .steps), to: self.stepsActivityView)
}
func layoutUI() {
contentView.addSubview(stepsActivityView)
stepsActivityView.translatesAutoresizingMaskIntoConstraints = false
let padding: CGFloat = 20
let itemHeight: CGFloat = 140
NSLayoutConstraint.activate([
stepsActivityView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: padding),
stepsActivityView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -padding),
stepsActivityView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: padding),
stepsActivityView.heightAnchor.constraint(equalToConstant: itemHeight),
])
print("TodayVC view width \(view.frame.size.width)")
}
func add(childVC: UIViewController, to containerView: UIView) {
addChild(childVC)
containerView.addSubview(childVC.view)
childVC.view.frame = containerView.bounds
childVC.didMove(toParent: self)
}
}
UIView 扩展:
extension UIView {
func addSubviews(_ views: UIView...) {
for view in views {
addSubview(view)
}
}
func pinToEdges(of superview: UIView) {
translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
topAnchor.constraint(equalTo: superview.topAnchor),
leadingAnchor.constraint(equalTo: superview.leadingAnchor),
trailingAnchor.constraint(equalTo: superview.trailingAnchor),
bottomAnchor.constraint(equalTo: superview.bottomAnchor),
])
}
}
MWStepsActivityVC:
class MWActivityVC: UIViewController {
let iconImageView = UIImageView()
let titleLabel = UILabel()
let counterLabel = UILabel()
init(activityType: ActivityType) {
super.init(nibName: nil, bundle: nil)
self.set(activityType: activityType)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
configureBackgroundView()
layoutUI()
placeholderData()
}
fileprivate func placeholderData() {
iconImageView.image = SFSymbols.steps
titleLabel.text = "StepsStepsStepsStepsStepsStepsStepsStepsStepsStepsStepsStepsStepsStepsStepsStepsStepsSteps"
counterLabel.text = "9000"
counterLabel.backgroundColor = .red
}
fileprivate func configureBackgroundView() {
view.layer.cornerRadius = 18
}
fileprivate func layoutUI() {
view.addSubviews(iconImageView, titleLabel, counterLabel)
iconImageView.translatesAutoresizingMaskIntoConstraints = false
titleLabel.translatesAutoresizingMaskIntoConstraints = false
counterLabel.translatesAutoresizingMaskIntoConstraints = false
let padding: CGFloat = 20
NSLayoutConstraint.activate([
iconImageView.topAnchor.constraint(equalTo: view.topAnchor, constant: padding),
iconImageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
iconImageView.heightAnchor.constraint(equalToConstant: 20),
iconImageView.widthAnchor.constraint(equalToConstant: 20),
titleLabel.centerYAnchor.constraint(equalTo: iconImageView.centerYAnchor),
titleLabel.leadingAnchor.constraint(equalTo: iconImageView.trailingAnchor, constant: padding),
titleLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),
titleLabel.heightAnchor.constraint(equalToConstant: 20),
counterLabel.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -padding),
counterLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
counterLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),
counterLabel.heightAnchor.constraint(equalToConstant: 40)
])
print("MWStepsActivityVC view width \(view.frame.size.width)")
}
}
我收到这些错误:
"<NSLayoutConstraint:0x600002228320 H:|-(20)-[UIImageView:0x7fc0abe077a0] (active, names: '|':UIView:0x7fc0abd10850 )>",
"<NSLayoutConstraint:0x6000022283c0 UIImageView:0x7fc0abe077a0.width == 20 (active)>",
"<NSLayoutConstraint:0x600002228460 H:[UIImageView:0x7fc0abe077a0]-(20)-[UILabel:0x7fc0abe08a70] (active)>",
"<NSLayoutConstraint:0x6000022284b0 UILabel:0x7fc0abe08a70.trailing == UIView:0x7fc0abd10850.trailing - 20 (active)>",
"<NSLayoutConstraint:0x600002230b90 'UIView-Encapsulated-Layout-Width' UIView:0x7fc0abd10850.width == 0 (active)>",
"<NSLayoutConstraint:0x600002228320 H:|-(20)-[UIImageView:0x7fc0abe077a0] (active, names: '|':UIView:0x7fc0abd10850 )>",
"<NSLayoutConstraint:0x600002228460 H:[UIImageView:0x7fc0abe077a0]-(20)-[UILabel:0x7fc0abe08a70] (active)>",
"<NSLayoutConstraint:0x6000022284b0 UILabel:0x7fc0abe08a70.trailing == UIView:0x7fc0abd10850.trailing - 20 (active)>",
"<NSLayoutConstraint:0x600002230b90 'UIView-Encapsulated-Layout-Width' UIView:0x7fc0abd10850.width == 0 (active)>",
"<NSLayoutConstraint:0x6000022285a0 H:|-(20)-[UILabel:0x7fc0abe08ce0] (active, names: '|':UIView:0x7fc0abd10850 )>",
"<NSLayoutConstraint:0x6000022285f0 UILabel:0x7fc0abe08ce0.trailing == UIView:0x7fc0abd10850.trailing - 20 (active)>",
"<NSLayoutConstraint:0x600002230b90 'UIView-Encapsulated-Layout-Width' UIView:0x7fc0abd10850.width == 0 (active)>"
我尝试使用wtfautolayout.com网站来了解问题所在,似乎问题在于UIView-Encapsulated-Layout-Width
它认为它设置为 0,但是当我尝试打印时,view.frame.size.width
我得到了正确的宽度:
MWStepsActivityVC view width 375.0
TodayVC view width 375.0
有人可以帮我吗?我已经为此苦苦挣扎了一天。
解决方案
最后我能够修复它。我忘了configureContainerViews
在主线程上运行...
DispatchQueue.main.async {
self.configureContainerViews()
}
推荐阅读
- ios - NavigationController 后退按钮导致“不支持多次推送同一个视图控制器实例”
- openlayers-6 - Openlayers 6 离线本地矢量 pbf 文件“未实现类型:6”错误
- java - Apache PDFBox - Adobe Acrobat 提示保存
- javascript - 在此网站上找到在 ajax 请求中生成 sha256Hash 参数的方法 - https://dutchie.com/dispensaries/taste-buds/menu
- php - 我在 href 中提供了一个链接以访问网络路由,但它在 laravel 5.6 中不起作用
- angular - 通过 Angular 中的工厂打开通用注入
- javascript - 处理网页中的图像时遇到问题
- sql - 如何在 Oracle 中将多行中的日期分组为一个?
- azure - 在 Azure 管道中的 VM 上远程运行 UI 测试
- python-3.x - 想要打印连续的 1