UIView没有响应触摸事件并且返回nil

时间:2018-01-09 08:56:59

标签: ios swift uiview uiwindow hittest

我正在尝试显示一个简单的自定义警报,这是一个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?()
            }
        }
    }
}

0 个答案:

没有答案