【问题标题】:Swipe Gesture on UITableview Cell Like Whtsapp does for "Reply a Message"在 UITableviewCell 上滑动手势,就像 Whatsapp 对“回复消息”所做的那样
【发布时间】:2021-03-17 21:32:47
【问题描述】:

我们如何在表格视图单元格上实现滑动手势并在手指从左向右移动时移动表格视图单元格?

我可以添加滑动手势,但移动单元格是我想要实现的。

Whatsapp 在回复消息时实现了相同的功能并希望获得相同的动画效果。

我们将不胜感激。

谢谢

【问题讨论】:

    标签: ios objective-c gesture swipe-gesture


    【解决方案1】:

    我为此创建了一个演示。你可以使用https://github.com/Dharmesh-shah2412/demoWhatsappSwipeToReply

    目标 C:

    我已将 PanGesture 添加到 Tableviewcell :

    - (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
        UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"Cell"];
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGestureCellAction:)];
        pan.delegate = self;
        [cell.contentView addGestureRecognizer:pan];
        return cell;
    }
    
    - (IBAction)panGestureCellAction:(UIPanGestureRecognizer *)recognizer {
        CGPoint translation = [recognizer translationInView:self.view];
        if (recognizer.view.frame.origin.x < 0) { return; }
        recognizer.view.center = CGPointMake(recognizer.view.center.x+ translation.x,
                                             recognizer.view.center.y );
        [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
        if(recognizer.view.frame.origin.x > [UIScreen mainScreen].bounds.size.width * 0.9)
        {
            [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
                [recognizer.view setFrame: CGRectMake(0, recognizer.view.frame.origin.y, recognizer.view.frame.size.width, recognizer.view.frame.size.height)];
            } completion:nil];
        }
        if (recognizer.state == UIGestureRecognizerStateEnded)
        {
            int x = recognizer.view.frame.origin.x;
            [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
                [recognizer.view setFrame: CGRectMake(0, recognizer.view.frame.origin.y, recognizer.view.frame.size.width, recognizer.view.frame.size.height)];
            } completion:^(BOOL finished) {
                if (x > recognizer.view.frame.size.width / 2) {
                    [_txtField becomeFirstResponder];
                }
            }];
        }
    }
    - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)panGestureRecognizer {
        CGPoint velocity = [panGestureRecognizer velocityInView:_tblView];
        if (velocity.x < 0) {
            return false;
        }
        return fabs(velocity.x) > fabs(velocity.y);
    }
    

    斯威夫特:

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panGestureCellAction))
        cell.contentView.addGestureRecognizer(panGestureRecognizer)
        return cell
    }
    
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let velocity : CGPoint = gestureRecognizer.location(in: tblView)
        if velocity.x < 0 {
            return false
        }
        return abs(Float(velocity.x)) > abs(Float(velocity.y))
    }
    
    @objc func panGestureCellAction(recognizer: UIPanGestureRecognizer)  {
        let translation = recognizer.translation(in: tblView)
        if recognizer.view?.frame.origin.x ?? 0 < 0 {
            return
        }
        recognizer.view?.center = CGPoint(
            x: (recognizer.view?.center.x ?? 0) + translation.x,
            y: (recognizer.view?.center.y ?? 0))
        recognizer.setTranslation(CGPoint(x: 0, y: 0), in: view)
        if (recognizer.view?.frame.origin.x ?? 0) > UIScreen.main.bounds.size.width * 0.9 {
            UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseOut, animations: {
                recognizer.view?.frame = CGRect(x: 0, y: recognizer.view?.frame.origin.y ?? 0, width: recognizer.view?.frame.size.width ?? 0, height: recognizer.view?.frame.size.height ?? 0)
            })
        }
        if recognizer.state == .ended {
            let x = recognizer.view?.frame.origin.x ?? 0
            UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseOut) {
                recognizer.view?.frame = CGRect(x: 0, y: recognizer.view?.frame.origin.y ?? 0, width: recognizer.view?.frame.size.width ?? 0, height: recognizer.view?.frame.size.height ?? 0)
            } completion: { (finished) in
                if x > ((recognizer.view?.frame.size.width ?? 0) / 2) {
                    self.txtChat.becomeFirstResponder()
                }
            }
        }
    }
    

    【讨论】:

    • 嗨,很快。我无法实施。 "- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)panGestureRecognizer", 总是"gestureRecognizerShouldBegin(_gestureRecognizer: UIGestureRecognizer) -> Bool"
    • @famfamfam 我添加了快速代码。请验证。
    • 这是一个有趣的解决方案。我只是希望我可以在消息的左侧添加回复图片。
    • @ekashking 您是否在消息左侧添加了回复图片?
    • 不,我没有继续使用此功能。
    猜你喜欢
    • 1970-01-01
    • 2020-09-03
    • 2018-01-25
    • 2023-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多