我有一个UICollectionView单元格,我想在聚焦时添加一些自定义视差动画。基本上,我将UIPanGestureRecognizer添加到焦点上的单元格contentView
,并在非焦点上删除它。然而,这不是最初的工作。
当我专注于一个单元格时,UIPanGestureRecognizer监听器函数 - viewPanned:
- 不会被调用。如果我将手指从遥控器上移开,然后再次触摸它,则只会viewPanned:
被调用。
更奇怪的是,如果我专注于不同的细胞,但是然后回到那个有效的细胞,那么它最初会起作用,而我不必将手指从遥控器上移开。
这是我的UIPanGestureRecognizer:
private lazy var panGesture: UIPanGestureRecognizer = {
let pan = UIPanGestureRecognizer(target: self,
action: Selector("viewPanned:")
)
pan.cancelsTouchesInView = false
return pan
}()
与焦点相关的代码:
// MARK: Focus
override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
super.didUpdateFocusInContext(context, withAnimationCoordinator: coordinator)
coordinator.addCoordinatedAnimations({ () -> Void in
if self.focused {
self.focusItem()
} else {
self.unfocusItem()
}
}) { () -> Void in
}
}
func focusItem() {
// -- (need slight delay otherwise jumps because of other focus animation
let dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
// print(" ---- adding pan")
self.contentView.addGestureRecognizer(self.panGesture)
})
}
func unfocusItem() {
contentView.removeGestureRecognizer(panGesture)
}
平移代码:
// MARK: Focus - Panning (Custom focus animation for rounded cells)
private var initialPanPosition: CGPoint?
func viewPanned(pan: UIPanGestureRecognizer) {
switch pan.state {
case .Began:
print(" ---- PAN -- BEGAN")
initialPanPosition = pan.locationInView(contentView)
case .Changed:
// print(" ---- PAN -- CHANGED")
if let initialPanPosition = initialPanPosition {
let currentPosition = pan.locationInView(contentView)
let diff = CGPoint(
x: currentPosition.x - initialPanPosition.x,
y: currentPosition.y - initialPanPosition.y
)
// -- parallax imageView
let parallaxCoefficientX = 1 / self.contentView.frame.width * 10
let parallaxCoefficientY = 1 / self.contentView.frame.height * 10
if (isRounded) {
self.imageView.transform = CGAffineTransformMakeTranslation(
diff.x * parallaxCoefficientX,
diff.y * parallaxCoefficientY
)
}
// -- parallax transformView
let parallaxCoefficientTransFormViewX = 1 / self.contentView.frame.width * 2
let parallaxCoefficientTransFormViewY = 1 / self.contentView.frame.height * 2
var transform = CATransform3DIdentity
if (!isRounded) { // -- not rounded cells already scale up the entire contentView
transform = CATransform3DScale(transform, Constants.FocusedTransformViewScaleTransform, Constants.FocusedTransformViewScaleTransform, 1.0)
}
transform = CATransform3DTranslate(transform,
diff.x * parallaxCoefficientTransFormViewX,
diff.y * parallaxCoefficientTransFormViewY,
0)
self.transformView.layer.transform = transform
}
default:
// .Canceled, .Failed, etc.. return the view to it's default state.
// print(" ---- PAN -- DEFAULT")
UIView.animateWithDuration(0.3,
delay: 0,
usingSpringWithDamping: 0.8,
initialSpringVelocity: 0,
options: .BeginFromCurrentState,
animations: { () -> Void in
if (self.isRounded) {
self.imageView.transform = CGAffineTransformMakeTranslation(1.0,1.0)
}
},
completion: nil)
}
}
修改
我没有在焦点/非焦点上添加/删除手势识别器,而是尝试在初始化时添加它并实现它:
override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
if (gestureRecognizer == panGesture) {
if (focused) {
return true
} else {
return false
}
}
return true
}
但是,由于某种原因,未聚焦的单元格仍会收到手势。添加/删除它是我可以阻止这种情况的唯一方法。
编辑#2
我也试过实现以下内容,认为焦点引擎手势识别器正在干扰,但它没有解决问题:
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}