gpt4 book ai didi

ios - 为什么这段添加 subview 的代码要按这个顺序执行?

转载 作者:行者123 更新时间:2023-11-28 05:57:05 25 4
gpt4 key购买 nike

我在长按后显示一个小 View (iconsContainerView),我不明白为什么 handleLongPress(gesture:) 中的代码以这种方式执行这是。据我了解,它应该从上到下,每一行都应该立即运行。这意味着一旦 view.addSubview(iconsContainerView) 运行, View 应该显示在屏幕的左上角,因为它的不透明度尚未设置为 0。

因此,编写的代码(一旦手势开始)看起来 View 将显示在左上角的屏幕上,然后在转换时移动,然后消失(当不透明度设置为 0 时),然后当不透明度设置为 1 时,重新出现在动画中。但实际情况是,在代码到达动画 block 之前, View 甚至不会显示。

所以,一切都按照我想要的方式运行——我确实希望 subview 在长按后淡入。但我只是想了解这背后的原因以及为什么每一行代码都没有立即执行(或者至少以这种方式显示在屏幕上)。它在主线程上运行,我在其中放置了断点并验证了这些行是否按顺序运行。

class ViewController: UIViewController {

let iconsContainerView: UIView = {
let containerView = UIView()
containerView.backgroundColor = .red

containerView.frame = CGRect(x: 0, y: 0, width: 200, height: 100)

return containerView
}()

override func viewDidLoad() {
super.viewDidLoad()

setUpLongPressGesture()
}

fileprivate func setUpLongPressGesture() {
view.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress)))
}

@objc func handleLongPress(gesture: UILongPressGestureRecognizer) {
print("Long gesture", Date())

if gesture.state == .began {
view.addSubview(iconsContainerView)

let pressedLocation = gesture.location(in: view)
let centeredX = (view.frame.width - iconsContainerView.frame.width) / 2

iconsContainerView.transform = CGAffineTransform(translationX: centeredX, y: pressedLocation.y - iconsContainerView.frame.height)

iconsContainerView.alpha = 0

UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {


self.iconsContainerView.alpha = 1

})


} else if gesture.state == .ended {
iconsContainerView.removeFromSuperview()
}
}

}

最佳答案

我想你期望你的代码像这样运行

you add a subview
system draws the view on the screen
you update the views transform
system redraws the view on the screen
you updates the views alpha
system redraws the view on the screen

由于您的代码在主线程上运行,系统绘图代码也在主线程上运行,因此它们不可能同时运行或在两者之间来回切换。

实际发生的是,您的应用在后台有一个始终运行的循环(RunLoop)。最简单的思考方式是它

handles input
draws views to the screen
repeat

您的代码将属于处理输入 部分。因此,您必须先完成整个方法的运行,然后循环才能进入下一步,即将 View 绘制到屏幕上。这也是为什么不要在主线程上做很多工作很重要,如果你的方法需要一秒钟来运行,这意味着应用程序无法绘制到屏幕或处理额外的输入一整秒,这将使该应用程序似乎卡住了。


边注

在现实中,主运行循环可以有更多的东西在里面进行。它还进行了很多优化,以确保它只在需要时运行,以避免在没有任何变化时不断运行 cpu 或重绘,这会破坏你的电池生命周期。对于大多数 iOS 开发来说,这应该足以理解,除非您开始直接与主运行循环交互或创建其他运行循环,但这很少需要。

关于ios - 为什么这段添加 subview 的代码要按这个顺序执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51165319/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com