Skip to content

Instantly share code, notes, and snippets.

@shima11
Last active December 1, 2020 02:20
Show Gist options
  • Select an option

  • Save shima11/6c734bcac156aa52798c2114cd878601 to your computer and use it in GitHub Desktop.

Select an option

Save shima11/6c734bcac156aa52798c2114cd878601 to your computer and use it in GitHub Desktop.
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