mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Sticker input rewrite continued
This commit is contained in:
@@ -13,6 +13,7 @@ swift_library(
|
||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||
"//submodules/Display:Display",
|
||||
"//submodules/Components/PagerComponent:PagerComponent",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
@@ -2,37 +2,172 @@ import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import PagerComponent
|
||||
|
||||
private final class ExpansionPanRecognizer: UIPanGestureRecognizer, UIGestureRecognizerDelegate {
|
||||
private var targetScrollView: UIScrollView?
|
||||
private func traceScrollView(view: UIView, point: CGPoint) -> (UIScrollView?, Bool) {
|
||||
for subview in view.subviews.reversed() {
|
||||
let subviewPoint = view.convert(point, to: subview)
|
||||
if subview.frame.contains(point) {
|
||||
let (result, shouldContinue) = traceScrollView(view: subview, point: subviewPoint)
|
||||
if let result = result {
|
||||
return (result, false)
|
||||
} else if subview.backgroundColor != nil {
|
||||
return (nil, false)
|
||||
} else if !shouldContinue{
|
||||
return (nil, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let scrollView = view as? UIScrollView {
|
||||
if scrollView is ListViewScroller || scrollView is GridNodeScrollerView {
|
||||
return (nil, false)
|
||||
}
|
||||
return (scrollView, false)
|
||||
}
|
||||
return (nil, true)
|
||||
}
|
||||
|
||||
private final class ExpansionPanRecognizer: UIGestureRecognizer, UIGestureRecognizerDelegate {
|
||||
enum LockDirection {
|
||||
case up
|
||||
case down
|
||||
}
|
||||
|
||||
override init(target: Any?, action: Selector?) {
|
||||
var requiredLockDirection: LockDirection = .up
|
||||
|
||||
private var beginPosition = CGPoint()
|
||||
private var currentTranslation = CGPoint()
|
||||
|
||||
override public init(target: Any?, action: Selector?) {
|
||||
super.init(target: target, action: action)
|
||||
|
||||
self.delegate = self
|
||||
}
|
||||
|
||||
override func reset() {
|
||||
self.targetScrollView = nil
|
||||
override public func reset() {
|
||||
super.reset()
|
||||
|
||||
self.state = .possible
|
||||
self.currentTranslation = CGPoint()
|
||||
}
|
||||
|
||||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
/*if let scrollView = otherGestureRecognizer.view as? UIScrollView {
|
||||
if scrollView.bounds.height > 200.0 {
|
||||
self.targetScrollView = scrollView
|
||||
scrollView.contentOffset = CGPoint()
|
||||
}
|
||||
}*/
|
||||
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
if let _ = otherGestureRecognizer.view as? PagerExpandableScrollView {
|
||||
return true
|
||||
}
|
||||
|
||||
if let _ = gestureRecognizer as? PagerPanGestureRecognizer {
|
||||
return true
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
if let _ = otherGestureRecognizer.view as? PagerExpandableScrollView {
|
||||
return true
|
||||
}
|
||||
if otherGestureRecognizer is UIPanGestureRecognizer {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
|
||||
override public func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
|
||||
super.touchesBegan(touches, with: event)
|
||||
|
||||
guard let touch = touches.first, let view = self.view else {
|
||||
self.state = .failed
|
||||
return
|
||||
}
|
||||
|
||||
var found = false
|
||||
let point = touch.location(in: self.view)
|
||||
if let _ = view.hitTest(point, with: event) as? UIButton {
|
||||
} else if let scrollView = traceScrollView(view: view, point: point).0 {
|
||||
let contentOffset = scrollView.contentOffset
|
||||
let contentInset = scrollView.contentInset
|
||||
if contentOffset.y.isLessThanOrEqualTo(contentInset.top) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if found {
|
||||
self.beginPosition = point
|
||||
} else {
|
||||
self.state = .failed
|
||||
}
|
||||
}
|
||||
|
||||
override public func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
|
||||
super.touchesMoved(touches, with: event)
|
||||
|
||||
if let targetScrollView = self.targetScrollView {
|
||||
targetScrollView.contentOffset = CGPoint()
|
||||
guard let touch = touches.first, let view = self.view else {
|
||||
self.state = .failed
|
||||
return
|
||||
}
|
||||
|
||||
let point = touch.location(in: self.view)
|
||||
|
||||
let translation = CGPoint(x: point.x - self.beginPosition.x, y: point.y - self.beginPosition.y)
|
||||
self.currentTranslation = translation
|
||||
|
||||
if self.state == .possible {
|
||||
if abs(translation.x) > 8.0 {
|
||||
self.state = .failed
|
||||
return
|
||||
}
|
||||
var lockDirection: LockDirection?
|
||||
let point = touch.location(in: self.view)
|
||||
if let scrollView = traceScrollView(view: view, point: point).0 {
|
||||
let contentOffset = scrollView.contentOffset
|
||||
let contentInset = scrollView.contentInset
|
||||
if contentOffset.y <= contentInset.top {
|
||||
lockDirection = self.requiredLockDirection
|
||||
}
|
||||
}
|
||||
if let lockDirection = lockDirection {
|
||||
if abs(translation.y) > 2.0 {
|
||||
switch lockDirection {
|
||||
case .up:
|
||||
if translation.y < 0.0 {
|
||||
self.state = .began
|
||||
} else {
|
||||
self.state = .failed
|
||||
}
|
||||
case .down:
|
||||
if translation.y > 0.0 {
|
||||
self.state = .began
|
||||
} else {
|
||||
self.state = .failed
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.state = .failed
|
||||
}
|
||||
} else {
|
||||
self.state = .changed
|
||||
}
|
||||
}
|
||||
|
||||
override public func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
|
||||
super.touchesEnded(touches, with: event)
|
||||
|
||||
self.state = .ended
|
||||
}
|
||||
|
||||
override public func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
|
||||
super.touchesCancelled(touches, with: event)
|
||||
|
||||
self.state = .cancelled
|
||||
}
|
||||
|
||||
func translation() -> CGPoint {
|
||||
return self.currentTranslation
|
||||
}
|
||||
|
||||
func velocity() -> CGPoint {
|
||||
return CGPoint()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +201,7 @@ public final class ChatInputPanelContainer: SparseNode, UIScrollViewDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
let delta = -recognizer.translation(in: self.view).y / scrollableDistance
|
||||
let delta = -recognizer.translation().y / scrollableDistance
|
||||
|
||||
self.expansionFraction = max(0.0, min(1.0, self.initialExpansionFraction + delta))
|
||||
self.expansionUpdated?(.immediate)
|
||||
@@ -75,7 +210,7 @@ public final class ChatInputPanelContainer: SparseNode, UIScrollViewDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
let velocity = recognizer.velocity(in: self.view)
|
||||
let velocity = recognizer.velocity()
|
||||
if abs(self.initialExpansionFraction - self.expansionFraction) > 0.25 {
|
||||
if self.initialExpansionFraction < 0.5 {
|
||||
self.expansionFraction = 1.0
|
||||
@@ -95,6 +230,11 @@ public final class ChatInputPanelContainer: SparseNode, UIScrollViewDelegate {
|
||||
self.expansionFraction = 1.0
|
||||
}
|
||||
}
|
||||
|
||||
if let expansionRecognizer = self.expansionRecognizer {
|
||||
expansionRecognizer.requiredLockDirection = self.expansionFraction == 0.0 ? .up : .down
|
||||
}
|
||||
|
||||
self.expansionUpdated?(.animated(duration: 0.4, curve: .spring))
|
||||
default:
|
||||
break
|
||||
@@ -107,7 +247,13 @@ public final class ChatInputPanelContainer: SparseNode, UIScrollViewDelegate {
|
||||
self.scrollableDistance = scrollableDistance
|
||||
}
|
||||
|
||||
public func expand() {
|
||||
self.expansionFraction = 1.0
|
||||
self.expansionRecognizer?.requiredLockDirection = self.expansionFraction == 0.0 ? .up : .down
|
||||
}
|
||||
|
||||
public func collapse() {
|
||||
self.expansionFraction = 0.0
|
||||
self.expansionRecognizer?.requiredLockDirection = self.expansionFraction == 0.0 ? .up : .down
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user