使用 UIPanGestureRecognizer 實現圖片跟隨手指拖曳移動的經典 iOS 交互效果,關鍵在於正確處理座標系轉換與位移重置。
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:@selector(pan:)];
UIImage *image = [UIImage imageNamed:@"your_image.jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 40, 80, 80)];
imageView.image = image;
imageView.userInteractionEnabled = YES; // 關鍵:啟用用戶交互
[self.view addSubview:imageView];
[imageView addGestureRecognizer:pan];
- (void)pan:(UIPanGestureRecognizer *)gesture {
// 獲取在父視圖座標系中的位移量
CGPoint translation = [gesture translationInView:self.view];
// 更新視圖中心點:當前中心 + 位移增量
gesture.view.center = CGPointMake(
gesture.view.center.x + translation.x,
gesture.view.center.y + translation.y
);
// 關鍵:重置位移量為零,避免累積誤差
[gesture setTranslation:CGPointZero inView:self.view];
}
| 關鍵點 | 說明 |
|---|---|
userInteractionEnabled = YES | UIImageView 預設關閉交互,必須啟用才能接收手勢事件 |
translationInView: | 返回手勢識別器視圖在指定視圖座標系中的位移向量 |
| 中心點更新 | 直接修改 center 屬性比修改 frame 更高效、無需重新計算尺寸 |
setTranslation:CGPointZero | 將位移歸零,確保下次回調獲得的是增量而非累積值 |
userInteractionEnabled 是否設為 YESsetTranslation:CGPointZero 在正確視圖座標系中調用gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: 協調手勢優先級// 添加彈性動畫效果
- (void)pan:(UIPanGestureRecognizer *)gesture {
if (gesture.state == UIGestureRecognizerStateEnded) {
[UIView animateWithDuration:0.3
delay:0
usingSpringWithDamping:0.5
initialSpringVelocity:0
options:0
animations:^{
// 吸附到邊緣或特定位置
gesture.view.center = targetCenter;
} completion:nil];
}
// ... 其餘邏輯
}