用户可以通过单击导航栏中的按钮将数据上传到我的Swift 5/Xcode 12.4应用程序中的服务器。当这发生时(在后台线程中异步),我正在显示一个自定义弹出窗口,并且没有一个常规按钮(包括导航栏中的按钮)应该是可点击的:
static func showIndicator(view: UIView) {
let parentView = UIView(frame: view.frame)
parentView.backgroundColor = UIColor.red.withAlphaComponent(0.5) //red only for testing, going to be set to 0.0 later
let indicatorContainer = UIView()
let width = 80
let height = 80
indicatorContainer.frame = CGRect(x: 0, y: 0, width: width, height: height)
indicatorContainer.center = view.center
indicatorContainer.backgroundColor = UIColor.darkGray.withAlphaComponent(0.97)
indicatorContainer.layer.cornerRadius = 8
indicatorContainer.clipsToBounds = true
let indicatorView = UIActivityIndicatorView(style: UIActivityIndicatorView.Style.large)
indicatorView!.center = CGPoint(x: width/2, y: height/2)
indicatorContainer.addSubview(indicatorView!)
parentView.addSubview(indicatorContainer)
view.addSubview(parentView)
indicatorView!.startAnimating()
}
从UIViewController
调用:
Toaster.showIndicator(view: self.view)
这使得它不可能触摸按钮,...在常规的UIView
中,它没有覆盖导航栏,理论上用户可以第二次启动上传过程(以及其他事情),这并不好。我发现了两种方法来防止这种情况发生:
1.使用uploadButton.isEnabled = false
暂时禁用导航栏中的按钮。这具有按钮变成灰色的缺点。
1.用一个不可见的UIView
覆盖整个区域,包括导航栏,但这也覆盖了状态栏,我不确定是否可以像这样简单地访问窗口:
static func showIndicator(view: UIView) {
let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow })!
let parentView = UIView(frame: window.frame)
...
parentView.addSubview(indicatorContainer)
window.addSubview(parentView)
indicatorView!.startAnimating()
}
我知道userInteractionEnabled
,但你不能把它用于UIBarButtonItem
,而且弹出窗口下面有太多其他可点击的UI元素,不能暂时禁用它们。
在应用程序中阻止按钮按下任何东西(=在弹出视图下面),而其他不应该被用户交互中断的事情正在发生时,首选的方法是什么?
3条答案
按热度按时间xyhw6mcr1#
问得好,看看视图层次结构
导航栏项目位于Toaster的前面,为了覆盖UIKit中的导航栏,您可以使用应用委托的window属性在导航栏上方添加自定义视图。这就是大多数第三方“烤面包机”框架(如MBProgressHUD)所做的。
因此,阻止烤面包机后面的每个触摸事件所需的最小变化是
kokeuurv2#
你可以使用类似这个函数的东西,它检查UIViewController中的所有视图,尝试转换它们以禁用用户交互。您可以添加任意多的类型。
该函数可以这样使用:
启用交互:toggleEditEnabled(editAllowed:真)
禁用交互:toggleEditEnabled(editAllowed:false)
ogq8wdun3#
在窗口上添加视图是最好的UI解决方案。从iOS 13开始,您可以通过self.view.window访问当前的
window
或者试试下面这个更快、更简单、更稳定的解决方案。只需在ViewController中创建一个标志变量,...
例如:
var isUploading = false