mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-16 19:30:29 +00:00
Fix item list scrolling for touches outside section blocks
This commit is contained in:
parent
2c52ee06de
commit
95b4d581cd
@ -184,6 +184,8 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
|||||||
|
|
||||||
public final var keepMinimalScrollHeightWithTopInset: CGFloat?
|
public final var keepMinimalScrollHeightWithTopInset: CGFloat?
|
||||||
|
|
||||||
|
public final var itemNodeHitTest: ((CGPoint) -> Bool)?
|
||||||
|
|
||||||
public final var stackFromBottom: Bool = false
|
public final var stackFromBottom: Bool = false
|
||||||
public final var stackFromBottomInsetItemFactor: CGFloat = 0.0
|
public final var stackFromBottomInsetItemFactor: CGFloat = 0.0
|
||||||
public final var limitHitTestToNodes: Bool = false
|
public final var limitHitTestToNodes: Bool = false
|
||||||
@ -3876,67 +3878,73 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.touchesPosition = touchesPosition
|
self.touchesPosition = touchesPosition
|
||||||
self.selectionTouchLocation = touches.first!.location(in: self.view)
|
|
||||||
|
|
||||||
self.selectionTouchDelayTimer?.invalidate()
|
var processSelection = true
|
||||||
self.selectionLongTapDelayTimer?.invalidate()
|
if let itemNodeHitTest = self.itemNodeHitTest, !itemNodeHitTest(touchesPosition) {
|
||||||
self.selectionLongTapDelayTimer = nil
|
processSelection = false
|
||||||
let timer = Timer(timeInterval: 0.08, target: ListViewTimerProxy { [weak self] in
|
}
|
||||||
if let strongSelf = self, strongSelf.selectionTouchLocation != nil {
|
|
||||||
strongSelf.clearHighlightAnimated(false)
|
if processSelection {
|
||||||
|
self.selectionTouchLocation = touches.first!.location(in: self.view)
|
||||||
if let index = strongSelf.itemIndexAtPoint(strongSelf.touchesPosition) {
|
self.selectionTouchDelayTimer?.invalidate()
|
||||||
var canBeSelectedOrLongTapped = false
|
self.selectionLongTapDelayTimer?.invalidate()
|
||||||
for itemNode in strongSelf.itemNodes {
|
self.selectionLongTapDelayTimer = nil
|
||||||
if itemNode.index == index && (strongSelf.items[index].selectable && itemNode.canBeSelected) || itemNode.canBeLongTapped {
|
let timer = Timer(timeInterval: 0.08, target: ListViewTimerProxy { [weak self] in
|
||||||
canBeSelectedOrLongTapped = true
|
if let strongSelf = self, strongSelf.selectionTouchLocation != nil {
|
||||||
}
|
strongSelf.clearHighlightAnimated(false)
|
||||||
}
|
|
||||||
|
|
||||||
if canBeSelectedOrLongTapped {
|
if let index = strongSelf.itemIndexAtPoint(strongSelf.touchesPosition) {
|
||||||
strongSelf.highlightedItemIndex = index
|
var canBeSelectedOrLongTapped = false
|
||||||
for itemNode in strongSelf.itemNodes {
|
for itemNode in strongSelf.itemNodes {
|
||||||
if itemNode.index == index && itemNode.canBeSelected {
|
if itemNode.index == index && (strongSelf.items[index].selectable && itemNode.canBeSelected) || itemNode.canBeLongTapped {
|
||||||
if true {
|
canBeSelectedOrLongTapped = true
|
||||||
if !itemNode.isLayerBacked {
|
}
|
||||||
strongSelf.reorderItemNodeToFront(itemNode)
|
}
|
||||||
for (_, headerNode) in strongSelf.itemHeaderNodes {
|
|
||||||
strongSelf.reorderHeaderNodeToFront(headerNode)
|
if canBeSelectedOrLongTapped {
|
||||||
|
strongSelf.highlightedItemIndex = index
|
||||||
|
for itemNode in strongSelf.itemNodes {
|
||||||
|
if itemNode.index == index && itemNode.canBeSelected {
|
||||||
|
if true {
|
||||||
|
if !itemNode.isLayerBacked {
|
||||||
|
strongSelf.reorderItemNodeToFront(itemNode)
|
||||||
|
for (_, headerNode) in strongSelf.itemHeaderNodes {
|
||||||
|
strongSelf.reorderHeaderNodeToFront(headerNode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
let itemNodeFrame = itemNode.frame
|
||||||
let itemNodeFrame = itemNode.frame
|
let itemNodeBounds = itemNode.bounds
|
||||||
let itemNodeBounds = itemNode.bounds
|
if strongSelf.items[index].selectable {
|
||||||
if strongSelf.items[index].selectable {
|
itemNode.setHighlighted(true, at: strongSelf.touchesPosition.offsetBy(dx: -itemNodeFrame.minX + itemNodeBounds.minX, dy: -itemNodeFrame.minY + itemNodeBounds.minY), animated: false)
|
||||||
itemNode.setHighlighted(true, at: strongSelf.touchesPosition.offsetBy(dx: -itemNodeFrame.minX + itemNodeBounds.minX, dy: -itemNodeFrame.minY + itemNodeBounds.minY), animated: false)
|
}
|
||||||
}
|
|
||||||
|
if itemNode.canBeLongTapped {
|
||||||
if itemNode.canBeLongTapped {
|
let timer = Timer(timeInterval: 0.3, target: ListViewTimerProxy {
|
||||||
let timer = Timer(timeInterval: 0.3, target: ListViewTimerProxy {
|
if let strongSelf = self, strongSelf.highlightedItemIndex == index {
|
||||||
if let strongSelf = self, strongSelf.highlightedItemIndex == index {
|
for itemNode in strongSelf.itemNodes {
|
||||||
for itemNode in strongSelf.itemNodes {
|
if itemNode.index == index && itemNode.canBeLongTapped {
|
||||||
if itemNode.index == index && itemNode.canBeLongTapped {
|
itemNode.longTapped()
|
||||||
itemNode.longTapped()
|
strongSelf.clearHighlightAnimated(true)
|
||||||
strongSelf.clearHighlightAnimated(true)
|
strongSelf.selectionTouchLocation = nil
|
||||||
strongSelf.selectionTouchLocation = nil
|
break
|
||||||
break
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, selector: #selector(ListViewTimerProxy.timerEvent), userInfo: nil, repeats: false)
|
||||||
}, selector: #selector(ListViewTimerProxy.timerEvent), userInfo: nil, repeats: false)
|
strongSelf.selectionLongTapDelayTimer = timer
|
||||||
strongSelf.selectionLongTapDelayTimer = timer
|
RunLoop.main.add(timer, forMode: RunLoop.Mode.common)
|
||||||
RunLoop.main.add(timer, forMode: RunLoop.Mode.common)
|
}
|
||||||
}
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, selector: #selector(ListViewTimerProxy.timerEvent), userInfo: nil, repeats: false)
|
||||||
}, selector: #selector(ListViewTimerProxy.timerEvent), userInfo: nil, repeats: false)
|
self.selectionTouchDelayTimer = timer
|
||||||
self.selectionTouchDelayTimer = timer
|
RunLoop.main.add(timer, forMode: RunLoop.Mode.common)
|
||||||
RunLoop.main.add(timer, forMode: RunLoop.Mode.common)
|
}
|
||||||
|
|
||||||
super.touchesBegan(touches, with: event)
|
super.touchesBegan(touches, with: event)
|
||||||
|
|
||||||
self.updateScroller(transition: .immediate)
|
self.updateScroller(transition: .immediate)
|
||||||
|
|||||||
@ -238,7 +238,9 @@ open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
|
|
||||||
self.listNode = ListView()
|
self.listNode = ListView()
|
||||||
self.leftOverlayNode = ASDisplayNode()
|
self.leftOverlayNode = ASDisplayNode()
|
||||||
|
self.leftOverlayNode.isUserInteractionEnabled = false
|
||||||
self.rightOverlayNode = ASDisplayNode()
|
self.rightOverlayNode = ASDisplayNode()
|
||||||
|
self.rightOverlayNode.isUserInteractionEnabled = false
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
@ -302,6 +304,14 @@ open class ItemListControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
let _ = strongSelf.contentScrollingEnded?(strongSelf.listNode)
|
let _ = strongSelf.contentScrollingEnded?(strongSelf.listNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.listNode.itemNodeHitTest = { [weak self] point in
|
||||||
|
if let strongSelf = self {
|
||||||
|
return point.x > strongSelf.leftOverlayNode.frame.maxX && point.x < strongSelf.rightOverlayNode.frame.minX
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let previousState = Atomic<ItemListNodeState?>(value: nil)
|
let previousState = Atomic<ItemListNodeState?>(value: nil)
|
||||||
self.transitionDisposable.set(((state
|
self.transitionDisposable.set(((state
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user