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

标签 ios swift user-interface modal-dialog segue

因此,我将尽可能多地提供有关该项目的信息。以下是与该问题相关的 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/

相关文章:

java - 在netbeans中使主板随着框架收缩和扩展

ios - imagePickerController 移动和缩放不起作用

iOS NSUserDefaults 同步完成前的访问

ios - 如何在iOS7中自定义UISearchBar(清除按钮)

Swift:尝试在实例函数中调用闭包时出错

java - 是否有公认的或新兴的 JSON 表单和字段定义格式?

ios - 如何在按下主页按钮时在 IOS 中显示顶部栏。?

ios - 在打开/加载之前加载/刷新 WKWebView

swift - 在 Swift 中扩展泛型类型的具体实例

java - 如何在 JTable 中呈现 JTable?