我正在尝试显示一个简单的自定义警报,这是一个UIView。显示警报的代码如下
if let alertController = try? OKAlertController.getAlertController(message: disclaimerText ?? NSAttributedString(string: ""), actions: [alertActionCancel, alertActionContinue]){
alertController.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
alertController.view.backgroundColor = UIColor.clear
在此之前调用多个线程,并在完成此代码时调用。 视图显示正确,但是当我尝试进行交互时,出现以下错误:
[Touch] unexpected nil window in __sendSystemGestureLatentClientUpdate,
_windowServerHitTestWindow:
<UIWindow: 0x7ff065e031a0;
frame = (0 0; 414 736);
autoresize = W+H;
userInteractionEnabled = NO;
gestureRecognizers = <NSArray: 0x60800005d3d0>;
layer = <UIWindowLayer: 0x608000221e80>
>,
touch:<UITouch: 0x7ff065d75520>
phase: Stationary
tap count: 1
force: 0.000
window: (null)
view: (null)
location in window: {0, 0}
previous location in window: {0, 0}
location in view: {0, 0}
previous location in view: {0, 0}
我确实尝试在主线程上运行显示逻辑但是没有用。 Stackoverflow建议重新初始化UIWindow,但这对我来说不是理想的行为。 任何帮助表示赞赏。
这是填充警报的类。它是一个UIViewController,里面有一个textview,底部有两个按钮。
class OKAlertController: UIViewController {
@IBOutlet private var buttons: [UIButton]!
@IBOutlet private weak var labelSeperator: UILabel!
@IBOutlet private weak var textViewMessageDisplayer: UITextView!
@IBOutlet private weak var contraintHeightTextView: NSLayoutConstraint!
private var alertActions: [OKAlertAction]?
static private let kMaximumActionCount = 2
static private let kAlertStoryBoardName = "AlertStoryBoard"
public class func getAlertController(message: NSAttributedString, actions: [OKAlertAction]) throws -> OKAlertController {
let storyboard = UIStoryboard(name: kAlertStoryBoardName, bundle: nil)
guard let alertController = storyboard.instantiateViewController(withIdentifier: Constants.Storyboard.GenericScreens.OKALertControllerID) as? OKAlertController else {
throw OKAlertError.viewLoadingFailed
}
if actions.count > OKAlertController.kMaximumActionCount {
throw OKAlertError.maxAlertAction
}
_ = alertController.view
alertController.setupView(message: message, actions: actions)
return alertController
}
/// Sets up the view for alert
///
/// - Parameters:
/// - message: Text to be displayed on the textView
/// - actions: Action handlers of the buttons
private func setupView(message: NSAttributedString, actions: [OKAlertAction]) {
textViewMessageDisplayer.attributedText = message
alertActions = actions
setButtonUI()
contraintHeightTextView.constant = textViewMessageDisplayer.contentSize.height >= contraintHeightTextView.constant ? contraintHeightTextView.constant : textViewMessageDisplayer.contentSize.height
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
handleBottomViewSetup()
}
/// Sets the button UI for the alert
private func setButtonUI() {
guard let actions = alertActions else { return }
for (index, action) in actions.enumerated() {
if index < buttons.count {
buttons[index].setAttributedTitle(action.actionText, for: .normal)
buttons[index].isHidden = false
}
}
}
/// Handles UI for one or two buttons
private func handleBottomViewSetup() {
if let actions = alertActions, actions.count < OKAlertController.kMaximumActionCount {
labelSeperator.removeFromSuperview()
buttons.last?.isHidden = true
}
}
@IBAction func buttonActionHandlers(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
if let index = buttons.index(of: sender), let actions = alertActions {
if index < actions.count {
let action = actions[index]
action.actionClosure?()
}
}
}
}