我正在尝试实现UINavigationBarDelegate,我想显示一条警告,让用户确定是否离开此视图。
这是我的代码:
extension CDFFormController: UINavigationBarDelegate {
public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
if let entityViewController = self.topViewController as? MyEntityViewController {
if entityViewController.isEditing {
let semaphore = DispatchSemaphore(value: 0)
var result = false
let alert = UIAlertController(title: "Leave the view?", message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "leave", style: .default, handler: { _ in
result = true
semaphore.signal()
}))
alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: { _ in
semaphore.signal()
}))
entityViewController.present(alert, animated: true, completion: nil)
semaphore.wait()
return result
} else {
return true
}
} else {
return true
}
}
}
我需要返回结果,所以我使用DispatchSemaphore来阻止该方法。但问题是:在主队列上调用此方法,阻塞它意味着阻止ui线程,方法永远不会返回。
或其他任何解决方案?
答案 0 :(得分:0)
我不确定它会起作用。我没试过这个。
extension CDFFormController: UINavigationBarDelegate {
public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
if let entityViewController = self.topViewController as? MyEntityViewController {
if entityViewController.isEditing {
let alert = UIAlertController(title: "Leave the view?", message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "leave", style: .default, handler: { _ in
let saveDelegate = navigationBar.delegate;
navigationBar.delegate = nil;
navigationBar.popItem(animated:YES);
navigationBar.delegate = saveDelegate;
}))
alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler:nil))
entityViewController.present(alert, animated: true, completion: nil)
return false
} else {
return true
}
} else {
return true
}
}
}
其他方式是使用RunLoop。但我不喜欢这样。
extension CDFFormController: UINavigationBarDelegate {
public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
if let entityViewController = self.topViewController as? MyEntityViewController {
if entityViewController.isEditing {
let state = 0
var result = false
let alert = UIAlertController(title: "Leave the view?", message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "leave", style: .default, handler: { _ in
state = 1
}))
alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: { _ in
state = 2
}))
entityViewController.present(alert, animated: true, completion: nil)
while (state == 0)
{
RunLoop.current.run(until: Date(timeIntervalSinceNow: 0.5))
}
return state == 1
} else {
return true
}
} else {
return true
}
}
}