UITableView Пользовательская кнопка Inset Action onSwipe - PullRequest
0 голосов
/ 21 сентября 2018

Я смог создать UITableViewCell, чтобы показать UIButton адаптирующий прохождение Рэя Вендерлиха здесь .

Целью была вставка со всех сторон contentView, где onPanLeft он будет вытягиваться справа uiButton с аналогичными верхними / нижними вставками.

Мне удалось этого добиться, однако у меня невероятно трудное время для решения одной проблемы:

  1. Если я начинаю медленно перетаскивать влево, contentView быстро разбрасывает влево / вправо назад и вперед.

Начальное состояние contentView с отступом 20 пунктов в начале или в конце к контейнеру UITableViewCell.

Завершение состояния ContentView с расширенной шириной (желтая линия - это то место, где должны встретиться синие / серые субвиды, голубая ширина субвидения - ИСПРАВЛЕНО)

Ниже приведен мой соответствующий код для справки:

var panStartPoint = CGPoint.zero
var startingRightLayoutConstraintConstant: CGFloat = 20

let kBounceValue: CGFloat = 20.0

func buttonTotalWidth() -> CGFloat {
    return deleteButton.frame.width
}

func updateConstraintsIfNeeded(_ animated: Bool, completion: @escaping (_ finished: Bool) -> Void) {
    var duration: Float = 0
    if animated {
        duration = 0.1
    }

    UIView.animate(withDuration: TimeInterval(duration), delay: 0, options: .curveEaseOut, animations: {
        self.layoutIfNeeded()
    }, completion: completion)
}

@objc func panThisCell(_ sender: UIPanGestureRecognizer) {

    if let cell = sender.view?.superview?.superview as? PostTableViewCell {
        switch sender.state {
        case .began:

            cell.panStartPoint = sender.translation(in: cell.myContentView)
            cell.startingRightLayoutConstraintConstant = cell.contentViewRightConstraint.constant
            break
        case .changed:
            let currentPoint: CGPoint = sender.translation(in: cell.myContentView)
            let deltaX: CGFloat = currentPoint.x - cell.panStartPoint.x
            var panningLeft = false

            if (currentPoint.x < cell.panStartPoint.x) { panningLeft = true }

            if (cell.startingRightLayoutConstraintConstant == 20) {
                if (!panningLeft) {
                    let constant: CGFloat = max(-deltaX, 20)

                    if (constant == 20) {
                        resetConstraintContstants(cell, toZero: true, notifyDelegateDidClose: true)
                    } else {
                        cell.contentViewLeftConstraint.constant = 20 - constant
                        cell.contentViewRightConstraint.constant = 20 + constant
                    }
                } else {
                    let constant: CGFloat = min(-deltaX, cell.buttonTotalWidth())
                    if (constant == cell.buttonTotalWidth()) {
                        setConstraintsToShowAllButtons(cell, true, notifyDelegateDidOpen: true)
                    } else {
                        cell.contentViewLeftConstraint.constant = 20 - constant
                        cell.contentViewRightConstraint.constant = 20 + constant
                    }
                }
            } else {
                let adjustment: CGFloat = cell.startingRightLayoutConstraintConstant - deltaX
                if (!panningLeft) {
                    let constant: CGFloat = max(adjustment, 20)
                    if (constant == 20) {
                        resetConstraintContstants(cell, toZero: true, notifyDelegateDidClose: true)
                    } else {
                        cell.contentViewLeftConstraint.constant = 20 - constant
                        cell.contentViewRightConstraint.constant = 20 + constant
                    }
                } else {
                    let constant: CGFloat = min(adjustment, cell.buttonTotalWidth())
                    if (constant == cell.buttonTotalWidth()) {
                        setConstraintsToShowAllButtons(cell, true, notifyDelegateDidOpen: true)
                    } else {
                        cell.contentViewLeftConstraint.constant = 20 - constant
                        cell.contentViewRightConstraint.constant = 20 + constant
                    }
                }
            }
        break
        case .ended:
            let halfOfButton: CGFloat = cell.deleteButton.frame.width / 2
                if cell.contentViewRightConstraint.constant >= halfOfButton {


                    setConstraintsToShowAllButtons(cell, true, notifyDelegateDidOpen: true)
                } else {
                    resetConstraintContstants(cell, toZero: true, notifyDelegateDidClose: true)
                }
            break
        case .cancelled:                
            if cell.startingRightLayoutConstraintConstant == 20 {
                resetConstraintContstants(cell, toZero: true, notifyDelegateDidClose: true)
            } else {
                setConstraintsToShowAllButtons(cell, true, notifyDelegateDidOpen: true)
            }
            break
        default:
            break
        }
    }
}

func setConstraintsToShowAllButtons(_ cell: PostTableViewCell, _ animated: Bool, notifyDelegateDidOpen notifyDelegate: Bool) {
    if cell.startingRightLayoutConstraintConstant == 20 + cell.buttonTotalWidth() && cell.contentViewRightConstraint.constant == 20 + cell.buttonTotalWidth() {
        return
    }
    cell.contentViewLeftConstraint.constant = 20 - cell.buttonTotalWidth() - cell.kBounceValue
    cell.contentViewRightConstraint.constant = 20 + cell.buttonTotalWidth() + cell.kBounceValue
    cell.deleteButtonTrailingConstraint.constant = cell.kBounceValue

    cell.updateConstraintsIfNeeded(animated) { finished in

        cell.contentViewLeftConstraint.constant = 20 - cell.buttonTotalWidth()
        cell.contentViewRightConstraint.constant = 20 + cell.buttonTotalWidth()
        cell.deleteButtonTrailingConstraint.constant = 0

        cell.updateConstraintsIfNeeded(animated) { finished in

            cell.startingRightLayoutConstraintConstant = cell.contentViewRightConstraint.constant
        }
    }
}

func resetConstraintContstants(_ cell: PostTableViewCell,toZero animated: Bool, notifyDelegateDidClose notifyDelegate: Bool) {
    if cell.startingRightLayoutConstraintConstant == 20 && cell.contentViewRightConstraint.constant == 20 {
        //Already all the way closed, no bounce necessary
        return
    }

    cell.contentViewRightConstraint.constant = 20 - cell.kBounceValue
    cell.contentViewLeftConstraint.constant = 20 + cell.kBounceValue
    cell.deleteButtonTrailingConstraint.constant = -cell.deleteButton.frame.width - cell.kBounceValue

    cell.updateConstraintsIfNeeded(animated) { finished in
        cell.contentViewRightConstraint.constant = 20
        cell.contentViewLeftConstraint.constant = 20
        cell.deleteButtonTrailingConstraint.constant = -cell.deleteButton.frame.width

        cell.updateConstraintsIfNeeded(animated) { finished in
            cell.startingRightLayoutConstraintConstant = cell.contentViewRightConstraint.constant
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Я написал оригинальное руководство, на которое ссылается этот вопрос, несколько лет назад, вскоре после выхода iOS 7.

Честно говоря, я бы действительно рекомендовал использовать методы tableView(_:editActionsForRowAt:) или tableView(_:trailingSwipeActionsConfigurationForRowAt:) UITableViewDelegate.Они официально поддерживаются и на намного проще, чем то, что я пытался там взломать.

Первый - iOS 8 и выше, второй - iOS 11 и выше.Я также подозреваю, что они могли изменить некоторые базовые архитектуры ячейки с тех пор, как было написано это руководство.

0 голосов
/ 21 сентября 2018

Вы можете попробовать, как показано ниже, с вашим изображением.

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {

    let moreClosure = { (action: UITableViewRowAction!, indexPath: NSIndexPath!) -> Void in
        println("More closure called")
    }

    let moreAction = UITableViewRowAction(style: .Normal, title: "  ", handler: moreClosure)

    if let image = UIImage(named: "image.png"){
        moreAction.backgroundColor = UIColor(patternImage: image)

    }
    return [moreAction]
}

Он отлично работает в моем приложении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...