gpt4 book ai didi

ios - 为什么我的 UI 元素在动画/缩放到屏幕外后无法正确重置?

转载 作者:行者123 更新时间:2023-11-30 12:16:34 25 4
gpt4 key购买 nike

因此,我将尽可能多地提供有关该项目的信息。以下是与该问题相关的 Storyboard部分的图像:

enter image description here

这是代码流程:

1) 用户玩游戏。这会打乱显示的表情符号,并最终隐藏右侧的所有表情符号。

2)当有人赢得游戏时,它会调用

performSegue(withIdentifier: "ShowWinScreenSegue", sender: self)

这将执行红色箭头指向的segue。此转场是模态转场,超过当前内容,交叉溶解。

3) 这里发生了一些事情,然后我尝试返回游戏屏幕,以便用户可以玩另一个游戏。这是我当前的代码

// self.delegate is the GameController that called the segue
// it's set somewhere else in the code so I can call these reset functions
GameController.gs = GameState()
guard let d = self.delegate else {
return
}
d.resetGameToMatchState()

dismiss(animated: true, completion: {
print("Modal dismiss completed")
GameController.gs = GameState()
self.delegate?.resetGameToMatchState()
})

所以这就是问题所在。您可以看到,我必须调用 delegate?.resetGameToMatchState() 两次才能真正发生任何事情。如果我删除第一个,当我调用第二个时什么也不会发生,反之亦然。让人如此烦人的是,用户会看到一个奇怪的跳转,所有 ui 都从旧状态转到新状态,因为它更新得这么晚而且间歇性地发生。

到目前为止我尝试过的
所以这整个问题让我对 UI 系统的工作原理感到非常困惑。

我的第一个想法是,该函数可能正在尝试更新对于 UI 线程来说执行得太早的线程中的 UI。因此,我将 resetGameToMatchState 的整个主体放入 DispatchQueue.main.async 调用中。这没有起到任何作用。

然后我认为它之前可以工作,因为当 WinScreenSegue 之前被解除时(当它是“显示”segue 时),它正在调用 GameControllerViewDidAppear 。我尝试在解雇回调中手动调用此函数,但这也不起作用,而且感觉很糟糕。

现在我陷入困境了:(任何帮助都将不胜感激。即使只是一点点信息可以澄清 UI 系统的工作原理。

这是我的resetGameToMatchState():

//reset all emoji labels
func resetGameToMatchState() {
DispatchQueue.main.async {
let tier = GameController.gs.tier

var i = 0
for emoji in self.currentEmojiLabels! {
emoji.frame = self.currentEmojiLabelInitFrames[i]
emoji.isHidden = false
emoji.transform = CGAffineTransform(scaleX: 1, y: 1);
i+=1
}

i=0
for emoji in self.goalEmojiLabels! {
emoji.frame = self.goalEmojiLabelInitFrames[i]
emoji.isHidden = false
emoji.transform = CGAffineTransform(scaleX: 1, y: 1);
i+=1
}

//match state
for i in 1...4 {
if GameController.gs.currentEmojis[i] == GameController.gs.goalEmojis[i] {
self.currentEmojiLabels?.findByTag(tag: i)?.isHidden = true
}
}

//reset highlight
let f = self.highlightBarInitFrame
let currentLabel = self.goalEmojiLabels?.findByTag(tag: tier)
let newSize = CGRect(x: f.origin.x, y: (currentLabel?.frame.origin.y)!, width: f.width, height: (currentLabel?.frame.height)! )
self.highlightBarImageView.frame = newSize

//update taps
self.updateTapUI()

//update goal and current emojis to show what the current goal/current selected emoji is
self.updateGoalEmojiLabels()
self.updateCurrentEmojiLabels()

}
}

更新
所以我刚刚发现了这一点。当我尝试重置用户界面时,唯一不起作用的是将右侧表情符号重置为其原始位置。我所做的是在应用程序开始时(在 viewDidLoad 中)运行以下命令:

for emoji in currentEmojiLabels! {
currentEmojiLabelInitFrames.append(emoji.frame)
}

这会保存它们的原始位置以供以后使用。我这样做是因为我在隐藏它们之前将它们动画到屏幕的一侧。
现在,当我想重置他们的位置时,我会这样做:

var i = 0
for emoji in self.currentEmojiLabels! {
emoji.frame = self.currentEmojiLabelInitFrames[i]
emoji.isHidden = false
emoji.transform = CGAffineTransform(scaleX: 1, y: 1);
i+=1
}

这应该将它们全部设置为原始框架和比例,但它没有正确设置位置。但它确实重置了比例。奇怪的是,我可以在屏幕左侧看到其中一个表情符号的一小部分,当它们动画时,它们会从左侧远处开始动画。我正在努力思考为什么框架如此偏离......

更新2
所以我尝试将框架重置代码更改为:

emoji.frame = CGRect(x: 25, y: 25, width: 25, height: 25)

我认为应该将它们正确重置到左上角,但它仍然将它们推到左侧。这应该证明 currentEmojiLabelInitFrames 不是问题,并且与我设置它们时有关。 也许约束被重置或搞乱了?

最佳答案

当模态 WinScreenController 被关闭时,您的第一个屏幕 GameController 应该从 UIKit 接收到 viewWillAppear 回调。

因此,其 resetGameToMatchState 函数可以简单地将属性设置为 true,然后您现有的 resetGameToMatchState 可以移至 viewWillAppear >,首先检查该属性是否正在设置。

var resetNeeded: Bool = false

func resetGameToMatchState() {
resetNeeded = true
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

// reset code here
}

关于ios - 为什么我的 UI 元素在动画/缩放到屏幕外后无法正确重置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45361896/

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