আমি আমার দৃষ্টিভঙ্গিটি ভাগ করে নিতে চাই কারণ অন্য সমস্ত পদ্ধতির হয় UIGestureRecognizerDelegateবা সাবক্লাসিংয়ের উপর ভিত্তি করে UIPanGestureRecognizer।
আমার পদ্ধতির রানটাইম এবং সুইজলিংয়ের উপর ভিত্তি করে। আমি এই পদ্ধতির বিষয়ে 100% নিশ্চিত নই, তবে আপনি নিজেই এটি পরীক্ষা করে উন্নত করতে পারেন।
UIPanGestureRecognizerকোডের এক লাইনের সাথে কোনওটির দিকনির্দেশ সেট করুন :
UITableView().panGestureRecognizer.direction = UIPanGestureRecognizer.Direction.vertical
ব্যবহার pod 'UIPanGestureRecognizerDirection'বা কোড:
public extension UIPanGestureRecognizer {
override open class func initialize() {
super.initialize()
guard self === UIPanGestureRecognizer.self else { return }
func replace(_ method: Selector, with anotherMethod: Selector, for clаss: AnyClass) {
let original = class_getInstanceMethod(clаss, method)
let swizzled = class_getInstanceMethod(clаss, anotherMethod)
switch class_addMethod(clаss, method, method_getImplementation(swizzled), method_getTypeEncoding(swizzled)) {
case true:
class_replaceMethod(clаss, anotherMethod, method_getImplementation(original), method_getTypeEncoding(original))
case false:
method_exchangeImplementations(original, swizzled)
}
}
let selector1 = #selector(UIPanGestureRecognizer.touchesBegan(_:with:))
let selector2 = #selector(UIPanGestureRecognizer.swizzling_touchesBegan(_:with:))
replace(selector1, with: selector2, for: self)
let selector3 = #selector(UIPanGestureRecognizer.touchesMoved(_:with:))
let selector4 = #selector(UIPanGestureRecognizer.swizzling_touchesMoved(_:with:))
replace(selector3, with: selector4, for: self)
}
@objc private func swizzling_touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
self.swizzling_touchesBegan(touches, with: event)
guard direction != nil else { return }
touchesBegan = true
}
@objc private func swizzling_touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
self.swizzling_touchesMoved(touches, with: event)
guard let direction = direction, touchesBegan == true else { return }
defer {
touchesBegan = false
}
let forbiddenDirectionsCount = touches
.flatMap({ ($0.location(in: $0.view) - $0.previousLocation(in: $0.view)).direction })
.filter({ $0 != direction })
.count
if forbiddenDirectionsCount > 0 {
state = .failed
}
}
}
public extension UIPanGestureRecognizer {
public enum Direction: Int {
case horizontal = 0
case vertical
}
private struct UIPanGestureRecognizerRuntimeKeys {
static var directions = "\(#file)+\(#line)"
static var touchesBegan = "\(#file)+\(#line)"
}
public var direction: UIPanGestureRecognizer.Direction? {
get {
let object = objc_getAssociatedObject(self, &UIPanGestureRecognizerRuntimeKeys.directions)
return object as? UIPanGestureRecognizer.Direction
}
set {
let policy = objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
objc_setAssociatedObject(self, &UIPanGestureRecognizerRuntimeKeys.directions, newValue, policy)
}
}
fileprivate var touchesBegan: Bool {
get {
let object = objc_getAssociatedObject(self, &UIPanGestureRecognizerRuntimeKeys.touchesBegan)
return (object as? Bool) ?? false
}
set {
let policy = objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
objc_setAssociatedObject(self, &UIPanGestureRecognizerRuntimeKeys.touchesBegan, newValue, policy)
}
}
}
fileprivate extension CGPoint {
var direction: UIPanGestureRecognizer.Direction? {
guard self != .zero else { return nil }
switch fabs(x) > fabs(y) {
case true: return .horizontal
case false: return .vertical
}
}
static func -(lhs: CGPoint, rhs: CGPoint) -> CGPoint {
return CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y)
}
}