Last active
December 1, 2020 02:20
-
-
Save shima11/6c734bcac156aa52798c2114cd878601 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class TooltipTouchDetectWindow: UIWindow, TouchableNodeWindowType { | |
| public var touchableNodeTable = NSHashTable<AnyTouchableNode>(options: .weakMemory) | |
| override final public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { | |
| let touchedView = super.hitTest(point, with: event) | |
| let touchedTooltipNodes = touchableNodeTable.allObjects.lazy.filter { tooltip -> Bool in | |
| tooltip.view | |
| .convert(tooltip.bounds, to: self) | |
| .contains(point) | |
| } | |
| ... | |
| // それぞれのResponderChainを配列にする | |
| let responderChainOfTouchedView: [UIResponder] = ResponderChainIterator(responder: touchedView).map { $0 } | |
| let responderChainOfTooltipView: [UIResponder] = ResponderChainIterator(responder: targetTooltipNode.view).map { $0 } | |
| // 一番最初に見つかる共通の親 | |
| let _parent = responderChainOfTouchedView.first { responderChainOfTooltipView.contains($0) } | |
| guard let parent = _parent else { | |
| return touchedView | |
| } | |
| // 共通の親から一つ手前のResponderを取得 | |
| func getChildResponder(parent: UIResponder, responderChain: [UIResponder]) -> UIResponder? { | |
| var presentResponder: UIResponder? = nil | |
| for responder in responderChain { | |
| if responder == parent { | |
| if presentResponder == nil { | |
| presentResponder = responder | |
| } | |
| break | |
| } | |
| presentResponder = responder | |
| } | |
| return presentResponder | |
| } | |
| guard let child1 = getChildResponder(parent: parent, responderChain: responderChainOfTouchedView) else { | |
| return touchedView | |
| } | |
| guard let child2 = getChildResponder(parent: parent, responderChain: responderChainOfTooltipView) else { | |
| return touchedView | |
| } | |
| var resultView: UIView? = nil | |
| if let parentView = parent as? UIView { | |
| // child1とchild2どちらがparentに対して前面にあるかを判定 | |
| for subview in parentView.subviews.reversed() { | |
| if subview === child1 { | |
| resultView = touchedView | |
| break | |
| } | |
| else if subview === child2 { | |
| resultView = targetTooltipNode.view | |
| break | |
| } | |
| } | |
| } | |
| guard resultView != nil else { | |
| return touchedView | |
| } | |
| return resultView | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment