- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
因此,我将尽可能多地提供有关该项目的信息。以下是与该问题相关的 Storyboard部分的图像:
这是代码流程:
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 时),它正在调用 GameController
的 ViewDidAppear
。我尝试在解雇回调中手动调用此函数,但这也不起作用,而且感觉很糟糕。
现在我陷入困境了:(任何帮助都将不胜感激。即使只是一点点信息可以澄清 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/
我有一个具有可变数量子元素的固定大小的 div。我不知道 children 的大小。目标是缩小它们以适合父级。 例子: .parent { width: 100px; height: 100p
我是一名优秀的程序员,十分优秀!