iOS - UIGestureRecognizer в UITableViewCell, похожий на Snapchat

Я пытаюсь реализовать функциональность в моем практическом приложении, очень похожем на приложение Snapchat, где вы перетаскиваете UITableViewCell вправо или влево, и при перетаскивании изображение позади представления медленно появляется, пока не достигнет определенной точки. , а после этого он начинает переход или переход типа PageViewController к другому контроллеру представления, который вы можете использовать для чата со своим другом.

Сначала я попытался использовать распознаватель жестов панорамирования края экрана, но он работает, только если вы начинаете смахивать от края экрана. Мне нужно провести пальцем из любого места в UITableViewCell.

Демонстрация моей необходимой функциональности находится в Snapchat, где вы видите это более четко, когда медленно проводите пальцем вправо по одной из ячеек таблицы вашего друга, и она медленно показывает изображение значка обмена сообщениями и в конечном итоге приводит к другому представлению, где вы можете общаться.

Так будет ли для этого достаточно распознавателя жестов панорамирования? Если да, то какой метод лучше всего использовать для этого? Я видел учебные пособия по распознавателям жестов панорамирования, но я не понимаю, как это может в конечном итоге привести к другому контроллеру представления после прокрутки определенного расстояния. Я думаю, что мог бы сойти с рук, поместив значок обмена сообщениями за отображаемым содержимым ячейки таблицы, которое могло появиться при смахивании вправо, но как я могу реализовать такую ​​плавную функциональность?

Изучение этого действительно улучшило бы мой опыт работы с пользователем. Будем признательны за любые советы или методы, спасибо.

РЕДАКТИРОВАТЬ: Пожалуйста, оставьте ответы в Objective C. Я не знаю Свифта.


person Rafi    schedule 02.04.2015    source источник


Ответы (1)


Для этого вы можете создать собственный TableViewCell. Код ниже должен делать то, что вы просите. Просто нужно добавить делегата в свой ViewController

protocol TableViewCellDelegate {
    func something()
}

class TableViewCell: UITableViewCell {

    var startSegue = false
    var label: UILabel                      // Or UIView, whatever you want to show
    var delegate: TableViewCellDelegate?    // Delegate to your ViewController to perform the segue

    required init(coder aDecoder: NSCoder) {
        fatalError("NSCoding not supported")
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {

        // Utility method for creating the label / view
        func createLabel() -> UILabel {
            let label = UILabel(frame: CGRect.nullRect)

            // Add label customization here

            return label
        }

        // Create "check" & "cross" labels for context cues
        label = createLabel()        // Create the label
        label.text = "\u{2713}"      // Add check symbol as text

        super.init(style: style, reuseIdentifier: reuseIdentifier)

        addSubview(label)

        // Add a pan recognizer
        var recognizer = UIPanGestureRecognizer(target: self, action: "handleSwipe:")
        recognizer.delegate = self
        addGestureRecognizer(recognizer)
    }

    let cueMargin: CGFloat = 10.0, cueWidth: CGFloat = 50.0

    override func layoutSubviews() {

        // The label starts out of view
        label.frame = CGRect(x: bounds.size.width + cueMargin, y: 0, width: cueWidth, height: bounds.size.height)
    }

    func handleSwipe(recognizer: UIPanGestureRecognizer) {
        let translation = recognizer.translationInView(self)

        if recognizer.state == .Changed {
            center = CGPointMake(center.x + translation.x, center.y)
            startSegue = frame.origin.x < -frame.size.width / 2.0                       // If swiped over 50%, return true
            label.textColor = startSegue ? UIColor.redColor() : UIColor.whiteColor()    // If swiped over 50%, become red
            recognizer.setTranslation(CGPointZero, inView: self)
        }
        if recognizer.state == .Ended {
            let originalFrame = CGRect(x: 0, y: frame.origin.y, width: bounds.size.width, height: bounds.size.height)
            if delegate != nil {
                startSegue ? delegate!.something() : UIView.animateWithDuration(0.2) { self.frame = originalFrame }
            }
        }
    }

    // Need this to handle the conflict between vertical swipes of tableviewgesture and pangesture
    override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
        if let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer {
            let velocity = panGestureRecognizer.velocityInView(superview!)
            if fabs(velocity.x) >= fabs(velocity.y) { return true }
            return false
        }
        return false
    }
}

Я получил это из этого руководство

РЕДАКТИРОВАТЬ: в вашем ViewController вам нужно будет `` зарегистрировать '' этот TableViewCell, используя:

yourTableName.registerClass(TableViewCell.self, forCellReuseIdentifier: "cellIdentifier")

И ваш TableViewDataSource для cellForRowAtIndexPath будет выглядеть так:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier", forIndexPath: indexPath) as TableViewCell

        cell.delegate = self

        // Add stuff for your other labels like:
        // "cell.name = item.name" etc        

       return cell
    }

Если вы хотите передать данные обратно в ViewController, просто используйте делегата.

person Henny Lee    schedule 02.04.2015
comment
Спасибо, но я не знаю Свифта. Есть ли способ получить это в Objective-C? Если нет, я постараюсь прочитать этот код и опробовать его, преобразовав в Objective C. Я вернусь к вам. Спасибо еще раз. - person Rafi; 03.04.2015
comment
Кроме того, если вы хотите, чтобы он отображался плавно, вы можете использовать альфа-значение для UIView (или метки) и установить его в диапазоне от 0 до ›1 на основе смахивания. Извините, я мало что знаю об Objective-C. Все, что я знаю, это скобки [] для методов вместо точечных обозначений в Swift. - person Henny Lee; 03.04.2015
comment
У меня немного поработал жест панорамирования ... но это еще не успех. Есть ли способ создать файл Swift, поместить туда этот код и сосуществовать с остальными моими файлами Objective-C? - person Rafi; 04.04.2015
comment
Я правильно ответил на этот вопрос, потому что он действительно дает мне то, что я хочу. Но я не могу сделать его совместимым с моим объективным кодом C. Тем не менее, большое спасибо и извините за то, что так долго помечали это правильно. - person Rafi; 17.04.2015
comment
np, а в чем проблема с смешиванием с вашим кодом obj-c? Вы также можете использовать автоматический макет для этого, может быть, это будет проще? - person Henny Lee; 17.04.2015