首页 > 解决方案 > 深不可测的行为:UIViewController 的 viewWillLayoutSubviews()

问题描述

我有: MyViewControllerUIViewController

VideoView是 的子类UIViewaPlayer是 的瞬间AVPlayer。并且aPlayer.layerVideoView' 层的子层。

slider是 的 瞬间UISlider并且elapsedTimeLabel是 的 瞬间UILabel。两者都是VideoView.

sliderelapsedTimeLabel使用自动布局约束定义:

slider = UISlider()
slider.translatesAutoresizingMaskIntoConstraints = false
slider.setThumbImage(UIImage(named: "sliderthumb.png"), for: .normal)
slider.setThumbImage(UIImage(named: "sliderthumb.png"), for: .selected)
slider.setThumbImage(UIImage(named: "sliderthumb.png"), for: .highlighted)
slider.addTarget(self, action: #selector(sliderValueChanged), for: .valueChanged)
controlsView.addSubview(slider)
let constraints4S = [
    slider.widthAnchor.constraint(equalToConstant: 200),
    slider.heightAnchor.constraint(equalToConstant: 40),
    slider.leftAnchor.constraint(equalTo: self.leftAnchor),
    slider.bottomAnchor.constraint(equalTo: self.bottomAnchor)
]
NSLayoutConstraint.activate(constraints4S)

elapsedTimeLabel = UILabel() 
elapsedTimeLabel.translatesAutoresizingMaskIntoConstraints = false
elapsedTimeLabel.font = UIFont.systemFont(ofSize: 14)
elapsedTimeLabel.text = "-00:00:00"
controlsView.addSubview(elapsedTimeLabel)
let constraints4L2 = [
    elapsedTimeLabel.widthAnchor.constraint(equalToConstant: 60),
    elapsedTimeLabel.heightAnchor.constraint(equalToConstant: 40),
    elapsedTimeLabel.leftAnchor.constraint(equalTo: slider.rightAnchor),
    elapsedTimeLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor)
]
NSLayoutConstraint.activate(constraints4L2)

在 VideoView 中有这个片段:

    let timeScale = CMTimeScale(NSEC_PER_SEC)
    let time = CMTime(seconds: 0.5, preferredTimescale: timeScale)
    let duration = self.aPlayer.currentItem?.asset.duration
    weak var weakSelf = self
    
    // Notify every half second
    timeObserverToken = self.aPlayer.addPeriodicTimeObserver(forInterval: time,
                                                             queue: .main)
    {
        [weakSelf] time in
        weakSelf!.elapsedTimeLabel.text = stringFromCMTime(time, nil)
        weakSelf!.slider.value = Float(CMTimeGetSeconds(time) / CMTimeGetSeconds(duration!))
    }

问题:在 MyViewController 中有这样的:

override func viewWillLayoutSubviews()
{
    super.viewWillLayoutSubviews()
    mySys(myClass: self, funcName: #function)
}

为什么播放的viewWillLayoutSubviews时候会一直触发。aPlayer经过一些测试,我发现如果我删除了这条线,它就会停止。

weakSelf!.elapsedTimeLabel.text = stringFromCMTime(time, nil)

为了测试我是否放置了 UIButton,它的行为与 UILabel 相同。但 UISlider 没有。此外,如果我不使用自动布局约束,那么它将正常运行。 viewWillLayoutSubviewsMyUIViewController不会被称为是。

它也发生在 Objective-C 版本中。

标签: iosobjective-cswiftautolayoutavplayer

解决方案


推荐阅读