为什么第二个视图控制器在 Playgrounds 环境中显示不正确?

问题描述

我在使用 Swift Playgrounds 时遇到了一个问题,该问题阻止我继续推进项目的进展。我注意到当 SecondViewController 出现时,它之前看起来更大;它所具有的约束(与之前的视图控制器类似)与 IntroductionViewController(第一个视图控制器)不同。

此项目是在 macOS 上的 Playgrounds 应用上创建的,而不是 Xcode。


问题

下面的两张图片分别显示了两个视图控制器:IntroductionViewControllerSecondViewController。请注意两个屏幕上的 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,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,dotView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor),])
    }
}

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() 语句移动到每个 VC 上的 layoutSubviews() 函数(在示例中进行了编辑,但仅包含设置 dotViewbeginButton 的拐角半径的代码)以前未显示的新值:

(701.0,805.0)
(701.0,805.0)
(778.5,1055.5)
(778.5714285714286,1055.844155844156)
(778.5714285714286,1055.844155844156)
(779.0,1056.0)
(599.5,380.5) [console opened?]

我假设 layoutSubviews() 是动态的,并且随着实时视图的重塑而积极变化。但是,我无法确定为什么实时视图会反映如此显着的差异,而这与设置的帧大小只有极小的差异。

不过,这就是我所知道的。这里出了什么问题,如何解决

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)