2013-03-12 148 views
4

我想在我的UITableViewController中實現一個UIPanGestureRecognizer以用於滑動刪除動畫。與清除應用程序中使用的滑動刪除類似,如果您在左側或右側滑動UITableViewCell,則單元格移動並被刪除。在UITableViewCell中使用UIPanGestureRecognizer的問題

我已經嘗試在我的UITableViewCell子類中實現這一點,但它似乎永遠不會收到事件。

這是我放在我的UITableViewCell子類嘗試此功能的代碼。在我的init方法

UIGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
    recognizer.delegate = self; 
    [self addGestureRecognizer:recognizer]; 

,然後方法來處理它:

- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer { 
CGPoint translation = [gestureRecognizer translationInView:self.superview]; 
//might have to change view to tableView 
//check for the horizontal gesture 
if (fabsf(translation.x) > fabsf(translation.y)) { 
    return YES; 
    NSLog(@"Panning"); 
} 
return NO; 
} 

- (void)handlePan:(UIPanGestureRecognizer *)recognizer { 
if (recognizer.state == UIGestureRecognizerStateBegan) { 
    //if the gesture has just started record the center location 
    NSLog(@"handlePan"); 
    _originalCenter = self.center; //Declared as a CGPoint at the top of my TableViewCell 
} 

if (recognizer.state == UIGestureRecognizerStateChanged) { 
    //translate the center (aka translate from the center of the cell) 
    CGPoint translation = [recognizer translationInView:self]; 
    self.center = CGPointMake(_originalCenter.x + translation.x, _originalCenter.y); 
    // determine whether the item has been dragged far enough to delete/complete 

} 

if (recognizer.state == UIGestureRecognizerStateEnded) { 
    // the frame this cell would have had before being dragged 
    CGRect originalFrame = CGRectMake(0, self.frame.origin.y, self.bounds.origin.x, self.bounds.size.height); 
    [UIView animateWithDuration:0.2 animations:^{ 
     self.frame = originalFrame;} 
    ]; 
} 
} 

細胞完全不動,雖然。不太確定這裏發生了什麼

+0

這會得到執行嗎?的NSLog(@ 「handlePan」); – 2013-03-12 20:51:09

+0

還將NSLog(@「panning」)移動到return語句上方,以便輸出。 – 2013-03-12 20:51:54

+0

這兩個日誌都不會執行。我不確定發生了什麼事。這些單元格都是完全固定的 – cherbear 2013-03-12 21:21:28

回答

5

如果你不想細胞的滑動手勢與表視圖滾動手勢同時發生,然後添加一個平移手勢到您的,並使其成爲一個代表:

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(doPan:)]; 
pan.delegate = self; 
[self addGestureRecognizer:pan]; 

並實現以下委託方法如果鍋水平只啓動:

#pragma mark - UIGestureRecognizerDelegate 

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 
{ 
    // note: we might be called from an internal UITableViewCell long press gesture 

    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { 

     UIPanGestureRecognizer *panGestureRecognizer = (UIPanGestureRecognizer*)gestureRecognizer; 
     UIView *cell = [panGestureRecognizer view]; 
     CGPoint translation = [panGestureRecognizer translationInView:[cell superview]]; 

     // Check for horizontal gesture 
     if (fabs(translation.x) > fabs(translation.y)) 
     { 
      return YES; 
     } 

    } 

    return NO; 
} 

Swift3 ..

override func awakeFromNib() { 
    super.awakeFromNib() 
    // do not use, say, layoutSubviews as layoutSubviews is called often 
    let p = UIPanGestureRecognizer(target: self, action: #selector(yourPan)) 
    p.delegate = self 
    contentView.addGestureRecognizer(p) 
    } 
} 

override func gestureRecognizerShouldBegin(_ g: UIGestureRecognizer) -> Bool { 
    if (g.isKind(of: UIPanGestureRecognizer.self)) { 
     let t = (g as! UIPanGestureRecognizer).translation(in: contentView) 
     let verticalness = abs(t.y) 
     if (verticalness > 0) { 
      print("ignore vertical motion in the pan ...") 
      print("the event engine will >pass on the gesture< to the scroll view") 
      return false 
     } 
    } 
    return true 
} 
+1

@JoeBlow:看起來不錯。一個評論:'layoutSubviews'可以被多次調用,所以你會添加多個手勢識別器,這可能不是一件好事。 – 2017-03-02 21:14:45

+0

非常感謝那個提示,@ jasonMoore.Sending a賞金! – Fattie 2017-03-03 12:15:21

0

將手勢識別器添加到內容視圖。

[self.contentView addGestureRecognizer:recognizer]; 
+0

我是否在UITableViewCell子類的'init'方法中執行此操作?編輯:將此代碼添加到'init'方法,仍然沒有得到任何東西。 – cherbear 2013-03-12 21:36:22

+0

「Panning」日誌現在出現在控制檯中,但只有在按住單元格一秒鐘後纔會出現。我希望我可以做到這一點,所以用戶不必一秒鐘就可以堅持下來,但只需輕掃即可使用。 – cherbear 2013-03-12 21:55:25

12

你需要下面的方法,以便在同步與滾動視圖的panGesture被檢測到的動作:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { 
    return YES; //otherGestureRecognizer is your custom pan gesture 
} 

記住的panGesture.delegate設爲您的viewController。 (更新了OlivaresF的評論。)

+0

這對我有用。請記住將viewController設置爲panGestureRecognizer委託,因此實際調用此方法。 此外,如果你這樣做,你的泛識別器將在用戶滾動tableView時觸發,所以你應該爲此做好準備。 – OlivaresF 2013-07-31 21:23:04

+0

解決了我的問題。謝謝! – 2014-06-09 09:48:26

+0

這基本上不是,真的,正確的**。你將手勢傳遞給滾動引擎;你並不是真的「都想要它們」(在幾乎所有的用例中,這會有點混亂)。傑森的回答完全正確。 – Fattie 2017-03-02 19:46:09