为什么我的 gestureRecognizer 返回零?
why is my gestureRecognizer returning nil?
我尝试结合许多教程来尝试让手势识别器在 tableView 上启动动画一旦在 mapView 上接收到手势(一旦地图移动就收缩 table旧的优步应用程序)。动画功能,但是一旦动画完成我收到 "unexpectedly found nil when unwrapping an optional" - 但它似乎不应该为零,显然它是,我只是不明白如何。错误是向下的 3/4,我试图减少尽可能多的代码,所以部分丢失了。我的猜测是我创建了 2 个导致问题的手势识别器,但我不确定如何组合它们。这是代码:
class RestaurantsVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UIGestureRecognizerDelegate {
var animator: UIViewPropertyAnimator?
var currentState: AnimationState!
var thumbnailFrame: CGRect!
var panGestureRecognizer: UIPanGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(RestaurantsVC.handlePan(gestureRecognizer:)))
panGestureRecognizer.delegate = self
self.mapView.addGestureRecognizer(panGestureRecognizer)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
@objc func handlePan (gestureRecognizer: UIPanGestureRecognizer) {
let translation = gestureRecognizer.translation(in: self.view.superview)
switch gestureRecognizer.state {
case .began:
startPanning()
animator?.startAnimation()
case .ended:
let velocity = gestureRecognizer.velocity(in: self.view.superview)
endAnimation(translation: translation, velocity: velocity)
default:
print("Something went wrong handlePan")
}
}
func startPanning() {
var finalFrame:CGRect = CGRect()
switch currentState {
// code
}
animator = UIViewPropertyAnimator(duration: 1, dampingRatio: 0.8, animations: {
})
}
func endAnimation (translation:CGPoint, velocity:CGPoint) {
if let animator = self.animator {
self.panGestureRecognizer.isEnabled = false //(this line is where i get the error)//
switch self.currentState {
case .thumbnail:
animator.isReversed = false
animator.addCompletion({ _ in
self.currentState = .minimized
self.panGestureRecognizer.isEnabled = true
})
case .minimized:
animator.isReversed = true
animator.addCompletion({ _ in
self.currentState = .thumbnail
self.panGestureRecognizer.isEnabled = true
})
default:
print("unknown state")
}
}
}
}
它是 nil
因为你从来没有真正分配它。
在您的 viewDidLoad()
函数中,您实际上是在 重新定义 一个隐藏实例变量的局部变量:
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(RestaurantsVC.handlePan(gestureRecognizer:)))
^ The 'let' keyword is redefining this variable at the local scope
您应该删除 let
声明,并将其指定为:
self.panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(RestaurantsVC.handlePan(gestureRecognizer:)))
这仍然可以在不存储对手势识别器的引用的情况下工作。您可以将传递到 handlePan
的手势识别器的值传递到 startAnimation
和 endAnimation
。这将减少在 class
上拥有多余属性的需要
我尝试结合许多教程来尝试让手势识别器在 tableView 上启动动画一旦在 mapView 上接收到手势(一旦地图移动就收缩 table旧的优步应用程序)。动画功能,但是一旦动画完成我收到 "unexpectedly found nil when unwrapping an optional" - 但它似乎不应该为零,显然它是,我只是不明白如何。错误是向下的 3/4,我试图减少尽可能多的代码,所以部分丢失了。我的猜测是我创建了 2 个导致问题的手势识别器,但我不确定如何组合它们。这是代码:
class RestaurantsVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UIGestureRecognizerDelegate {
var animator: UIViewPropertyAnimator?
var currentState: AnimationState!
var thumbnailFrame: CGRect!
var panGestureRecognizer: UIPanGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(RestaurantsVC.handlePan(gestureRecognizer:)))
panGestureRecognizer.delegate = self
self.mapView.addGestureRecognizer(panGestureRecognizer)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
@objc func handlePan (gestureRecognizer: UIPanGestureRecognizer) {
let translation = gestureRecognizer.translation(in: self.view.superview)
switch gestureRecognizer.state {
case .began:
startPanning()
animator?.startAnimation()
case .ended:
let velocity = gestureRecognizer.velocity(in: self.view.superview)
endAnimation(translation: translation, velocity: velocity)
default:
print("Something went wrong handlePan")
}
}
func startPanning() {
var finalFrame:CGRect = CGRect()
switch currentState {
// code
}
animator = UIViewPropertyAnimator(duration: 1, dampingRatio: 0.8, animations: {
})
}
func endAnimation (translation:CGPoint, velocity:CGPoint) {
if let animator = self.animator {
self.panGestureRecognizer.isEnabled = false //(this line is where i get the error)//
switch self.currentState {
case .thumbnail:
animator.isReversed = false
animator.addCompletion({ _ in
self.currentState = .minimized
self.panGestureRecognizer.isEnabled = true
})
case .minimized:
animator.isReversed = true
animator.addCompletion({ _ in
self.currentState = .thumbnail
self.panGestureRecognizer.isEnabled = true
})
default:
print("unknown state")
}
}
}
}
它是 nil
因为你从来没有真正分配它。
在您的 viewDidLoad()
函数中,您实际上是在 重新定义 一个隐藏实例变量的局部变量:
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(RestaurantsVC.handlePan(gestureRecognizer:)))
^ The 'let' keyword is redefining this variable at the local scope
您应该删除 let
声明,并将其指定为:
self.panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(RestaurantsVC.handlePan(gestureRecognizer:)))
这仍然可以在不存储对手势识别器的引用的情况下工作。您可以将传递到 handlePan
的手势识别器的值传递到 startAnimation
和 endAnimation
。这将减少在 class