我在使用 Swift Playgrounds 时遇到了一个问题,该问题阻止我继续推进项目的进展。我注意到,当SecondViewController
呈现时,它以前看起来更大;它具有的约束(类似于以前的视图控制器)没有反映类似于IntroductionViewController
第一个视图控制器。
这个项目是在 macOS 上的Playgrounds应用程序上创建的,而不是 Xcode。
问题
下面的两张图片分别显示了两个视图控制器:IntroductionViewController
和SecondViewController
。注意UIStackView
两个屏幕上的(蓝色背景)如何不共享相同的水平约束。
编码
这是IntroductionViewController
. 为了减少,只显示我怀疑可能导致该问题的基本代码位:
import UIKit
private protocol IntroductionDelegate {
func beginButtonTapped()
}
private class IntroductionView: UIView {
lazy var dotView: UIView = {
let dotView = UIView()
dotView.backgroundColor = .label
dotView.translatesAutoresizingMaskIntoConstraints = false
return dotView
}()
// [Redacted code]: titleLabel, subtitleLabel, beginButton
lazy var stackView: UIStackView = {
let stackView = UIStackView()
stackView.alignment = .center
stackView.distribution = .fillProportionally
stackView.addSubview(dotView)
stackView.addSubview(titleLabel)
stackView.addSubview(subtitleLabel)
stackView.addSubview(beginButton)
stackView.backgroundColor = .blue
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
var delegate: IntroductionDelegate?
// [Redacted code]: Required inits
private func configureLayout() {
NSLayoutConstraint.activate([
stackView.rightAnchor.constraint(equalTo: rightAnchor, constant: -100.0),
stackView.leftAnchor.constraint(equalTo: leftAnchor, constant: 100.0),
stackView.centerXAnchor.constraint(equalTo: centerXAnchor),
stackView.centerYAnchor.constraint(equalTo: centerYAnchor),
dotView.topAnchor.constraint(equalTo: stackView.topAnchor),
dotView.centerXAnchor.constraint(equalTo: stackView.centerXAnchor),
dotView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.1),
dotView.widthAnchor.constraint(equalTo: dotView.heightAnchor),
// [Redacted code]
beginButton.topAnchor.constraint(equalTo: subtitleLabel.bottomAnchor, constant: 40.0),
beginButton.rightAnchor.constraint(equalTo: stackView.rightAnchor),
beginButton.bottomAnchor.constraint(equalTo: stackView.bottomAnchor),
beginButton.leftAnchor.constraint(equalTo: stackView.leftAnchor),
beginButton.heightAnchor.constraint(equalToConstant: 65.0)
])
}
@objc func begin() {
beginButton.isEnabled = false
UIView.animate(withDuration: 1.5, delay: 0.0, options: .curveEaseInOut, animations: {
// [Redacted code]: Animations
}, completion: { (nil) in
NSLayoutConstraint.activate([
self.dotView.bottomAnchor.constraint(equalTo: self.stackView.bottomAnchor)
])
UIView.animate(withDuration: 0.75, delay: 0.5, options: .curveEaseInOut, animations: {
// [Redacted code]: Animations
}, completion: { (nil) in
self.delegate?.beginButtonTapped()
})
})
}
}
public class IntroductionViewController: UIViewController, IntroductionDelegate {
func beginButtonTapped() {
let secondVC = SecondViewController()
secondVC.modalPresentationStyle = .fullScreen
print(view.frame.size)
secondVC.screenSize = view.frame.size
self.present(secondVC, animated: false, completion: nil)
}
public override func loadView() {
let view = IntroductionView()
view.delegate = self
self.view = view
}
}
以下是代码SecondViewController
:
import UIKit
class SecondView: UIView {
lazy var dotView: UIView = {
let dotView = UIView()
dotView.backgroundColor = .label
dotView.translatesAutoresizingMaskIntoConstraints = false
return dotView
}()
lazy var stackView: UIStackView = {
let stackView = UIStackView()
stackView.alignment = .center
stackView.distribution = .fillProportionally
stackView.addSubview(dotView)
stackView.backgroundColor = .blue
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
// [Redacted code]: Required inits
private func configureLayout() {
NSLayoutConstraint.activate([
stackView.rightAnchor.constraint(equalTo: rightAnchor, constant: -100.0),
stackView.leftAnchor.constraint(equalTo: leftAnchor, constant: 100.0),
stackView.centerXAnchor.constraint(equalTo: centerXAnchor),
stackView.centerYAnchor.constraint(equalTo: centerYAnchor),
dotView.topAnchor.constraint(equalTo: stackView.topAnchor),
dotView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor),
dotView.centerXAnchor.constraint(equalTo: stackView.centerXAnchor),
dotView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.1),
dotView.widthAnchor.constraint(equalTo: dotView.heightAnchor),
])
}
}
public class SecondViewController: UIViewController {
public var screenSize: CGSize?
public override func loadView() {
let view = SecondView()
view.frame.size = screenSize!
print(view.frame.size)
self.view = view
}
}
尝试
我包含两个print()
语句来获取视图框架的大小,只是为了查看视图是否正确调整大小。果然,我在控制台中得到了以下信息:
(778.5, 1055.5)
(778.5, 1055.5)
将print()
语句移至layoutSubviews()
每个 VC 上的函数(在示例中进行了编辑,但仅包含设置 和 的角半径的代码dotView
)beginButton
揭示了以前未显示的新值:
(701.0, 805.0)
(701.0, 805.0)
(778.5, 1055.5)
(778.5, 1055.5)
(778.5, 1055.5)
(778.5714285714286, 1055.844155844156)
(778.5714285714286, 1055.844155844156)
(779.0, 1056.0)
(599.5, 380.5) [console opened?]
我假设它layoutSubviews()
是动态的,并且随着实时视图的重塑而积极变化。虽然,我无法确定为什么实时视图会反映如此显着的差异,而这与设置的帧大小只有极小的差异。
不过,这就是我所知道的。这里出了什么问题,如何解决?