ios - UIBarButton 调用操作后无法更改 UIView.isHidden 属性
问题描述
我正在使用UIView
'sisHidden
属性在我正在开发的发布界面上显示/隐藏控件。我使用它来更改键盘向上/向下时可用的控件,选择帖子类型等。我编写了一个由通知触发的方法,该方法设置视图属性(主要是.isHidden
)并动画更改,当键盘出现时调用,或者当用户选择一个帖子类型,然后更改可供他们使用的控件时。这通常可以正常工作,并且属性会按预期更改,但是当该方法由UIBarButton
操作触发时,设置为可见的视图变得无响应。点击栏按钮后,我无法更改isHidden
视图的属性(即使通过显式设置isHidden
为真或假......它也不会改变)。
这是更改视图属性的方法:
@objc func animateActionViewChange(_ sender: Notification) {
// DEBUG
print("\n[BEFORE]\nnormalActionView.isHidden: \(normalActionView.isHidden)\nkeyboardActionView.isHidden: \(keyboardActionView.isHidden)\nkeyboardUp: \(keyboardUp)\nactionViewActive: \(actionViewActive)")
// save prev state
let normalTemp: Bool = normalActionView.isHidden
let keyboardTemp: Bool = keyboardActionView.isHidden
// set new state based on env vars
normalActionView.isHidden = keyboardUp ? true : !actionViewActive
keyboardActionView.isHidden = keyboardUp ? !actionViewActive : true
// DEBUG
print("[AFTER]\nnormalActionView.isHidden: \(normalActionView.isHidden)\nkeyboardActionView.isHidden: \(keyboardActionView.isHidden)\nkeyboardUp: \(keyboardUp)\nactionViewActive: \(actionViewActive)")
// animate opacity changes
if normalActionView.isHidden != normalTemp {
let targetAlpha: CGFloat = normalTemp ? CGFloat(1) : CGFloat(0)
UIView.animate(withDuration: actionViewAnimationDuration / 2) {
self.normalActionView.alpha = targetAlpha
}
}
if keyboardActionView.isHidden != keyboardTemp {
let targetAlpha: CGFloat = keyboardTemp ? CGFloat(1) : CGFloat(0)
UIView.animate(withDuration: actionViewAnimationDuration / 2) {
self.keyboardActionView.alpha = targetAlpha
}
}
}
以及调用的操作UIBarButton
(此问题涉及按钮标题为“返回”时):
// back/cancel button action
@IBAction func cancel(sender: UIBarButtonItem) {
if sender.title == "Cancel" {
// cancel ongoing request if there is one
if let request = ongoingRequest {
if !request.isFinished {
request.cancel()
}
}
self.performSegue(withIdentifier: "cancel_unwindFromNewPostView", sender: self)
} else {
// reset post type to default (general)
postType = .general
// set actionViewActive bool to set visibility going forwards
actionViewActive = true
// hide datePicker
self.datePickerView.isHidden = true
actionViewAnimationDuration = 0.35
NotificationCenter.default.post(name: NSNotification.Name("animateActionViewChange"), object: nil)
UIView.animate(withDuration: 0.35) {
// layout
self.view.layoutIfNeeded()
}
// revert button text to 'cancel'
cancelButton.title = "Cancel"
}
}
这是点击“返回”按钮之前调试标志的输出:
[BEFORE]
normalActionView.isHidden: false
keyboardActionView.isHidden: true
keyboardUp: true
actionViewActive: true
[AFTER]
normalActionView.isHidden: true
keyboardActionView.isHidden: false
keyboardUp: true
actionViewActive: true
后:
[BEFORE]
normalActionView.isHidden: true
keyboardActionView.isHidden: true
keyboardUp: false
actionViewActive: true
[AFTER]
normalActionView.isHidden: true
keyboardActionView.isHidden: true
keyboardUp: false
actionViewActive: true
正如您在上面看到isHidden
的,普通操作视图的属性没有改变,即使它被设置为“假”。我最初认为这是因为引用在某处丢失(尽管我认为这会导致 nil 引用,而我没有),所以我做了引用normalActionView
和keyboardActionView
强引用。显然,这并没有解决问题,所以我将更改放在isHidden
通知调用的方法中,以确保它始终在同一个线程上(确实如此,我通过打印当前线程进行检查,它始终是主线程),但这也无济于事。
解决方案
isHidden
表现得好像它是累积的。例如,如果您将其设置true
为连续两次,则需要将其设置为false
两次。
我通常在设置值之前检查相反的值。
if view.isHidden == false {
view.isHidden = true
}
推荐阅读
- android - Flutter ListView 小部件未导出为 JSON 字符串:使用 dynamic_widget 和 DynamicWidgetJsonExportor
- node.js - 如何在 .ejs 文件中运行在数据库中保存为字符串的自定义代码
- c# - 具有依赖属性的 C# 类
- python - 创建一个有效的算法来查找时间范围列表中的所有并发时间范围
- java - 我可以在java中的1个方法中做多个switch case吗?
- angular - 无法从角度使用星云自动完成控制
- python - Python Tensorflow 如何使用数据库中的模型?
- vue.js - 如何在 Nuxt.js 中获得 Stack Overflow SEO 友好的 URL 结构?
- sql - Azure Data Studio 不遵守 PostgreSQL 的指定大小写
- databricks - 输入 DBFS 上文件的正确路径