0

我在使用 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, 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 上的函数(在示例中进行了编辑,但仅包含设置 和 的角半径的代码dotViewbeginButton揭示了以前未显示的新值:

(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()是动态的,并且随着实时视图的重塑而积极变化。虽然,我无法确定为什么实时视图会反映如此显着的差异,而这与设置的帧大小只有极小的差异。

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

4

0 回答 0