如何使用 UIKit 在 Swift 5 中立即强制更新我的 UI?

Posted

技术标签:

【中文标题】如何使用 UIKit 在 Swift 5 中立即强制更新我的 UI?【英文标题】:How can I force update my UI immediately in Swift 5 using UIKit? 【发布时间】:2020-05-16 18:58:10 【问题描述】:

我的 UI 出现问题,无法立即更新。

我先打电话给someCustomView.isHidden = false。之后,我创建了一个新的View Controller 的新实例。在新的 VC viewDidLoad() 中,我正在加载一个“新的机器学习模型”,这需要一些时间。

private func someFuncThatGetsCalled() 

    print("1")

    self.viewLoading.isHidden = false

    print("2")

    performSegue(withIdentifier: "goToModelVCSegue", sender: nil)


只要我按下调用此函数的按钮,控制台就会打印“1”和“2”。但是,在我的新 VC 的 viewDidLoad() 完成之前,该视图是不可见的。

是否有可能立即强制更新UIViewsetNeedsDisplay() 对我不起作用。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

使用layoutIfNeeded()Apple Docs

layoutIfNeeded()

如果布局更新未决,则立即布局子视图。 使用此方法强制视图立即更新其布局。使用自动布局时,布局引擎会根据需要更新视图的位置以满足约束的变化。使用接收消息的视图作为根视图,该方法从根开始布局视图子树。如果没有待处理的布局更新,则此方法退出而不修改布局或调用任何与布局相关的回调。

所以根据经验,

layoutifneeded:立即(当前更新周期),同步调用

setNeedsLayout:放松(等到下一个更新周期),异步调用

所以,layoutIfNeeded 说请立即更新,而setNeedsLayout 说请更新,但您可以等到下一个更新周期。

如何使用

yourView.layoutIfNeeded()

您还可以参考图表以更好地记住这些遍的顺序

来源Apple docs on layoutIfNeeded

图片来源Medium artcle

【讨论】:

【参考方案2】:

几个问题...

如果您有一个 “需要一些时间” 加载的视图控制器,则不应尝试以这种方式进行。

应用将无响应并显示为“冻结”。

更好的方法是:

someFuncThatGetsCalled() 隐藏 viewLoading 并将其替换为活动指示器(微调器或其他让用户知道应用没有卡住的东西) 实例化你的ModelVC ModelVC 完成设置后,通知当前 VC(通过委托) 当前的 VC 然后显示/导航到已经实例化和准备好的ModelVC

或者,可能是更好的选择...将您在ModelVC 中的耗时设置移动到视图出现之后。您可以在viewDidLoad() 中显示活动指示器。这确实是最常见的 UX——当新的 VC 必须检索远程数据以显示时,你总是会看到它——它符合用户的期望。

【讨论】:

感谢您的回答。这是解决问题的另一个好主意。

以上是关于如何使用 UIKit 在 Swift 5 中立即强制更新我的 UI?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 UIKit 在 Swift 5 中创建具有内在高度的 UITableView?

如何消除 animateKeyframes 动画开始和结束的延迟 - Swift UIKit

如何在 Swift 中使用 UIKit 注册多个按钮点击?

如何使用 iOS Swift SKOverlay 和 UIKit 来交叉推广另一个应用程序?

如何在 Swift UIKit 的 if 语句中显示多个警报?

如何在 Swift UIKit Map 组件中处理 SwiftUI 中的触摸手势?