webentwicklung-frage-antwort-db.com.de

wie man Zellen in der uitableview-Ansicht nach links und rechts bewegt, ein Bild links und ein Bild rechts

Wie dargestellt, muss ich beim Wischen nach links einen Button mit einem Bild anzeigen, den blauen, und wenn Sie nach rechts wischen, wird der grüne Button angezeigt. Wie soll das gehen? Ich verwende Swift und Xcode 6.4

Das habe ich versucht, bevor ich gefragt habe. Ich konnte zwei Optionen mit Text rechts von einer Zelle anzeigen, aber ich möchte das nicht. Was benötigt wird, ist in der Abbildung. Wie gesagt, die Schaltflächen müssen Bilder sein kein Text.

 enter image description here

15
DeyaEldeen

Sie können die Unterklasse UITableViewCell einschließen, um einen UIPanGestureRecognizer aufzunehmen, der den contentViews-Rahmen der Zelle bearbeitet und Ihre Schaltflächen hinter dem contentView hinzufügt.

Um zu sehen, wie dies im Detail funktionieren kann, habe ich Beispielcode hinzugefügt, wie das unten als Referenz beschrieben wird. Dadurch wird auch eine Tippen-Gesten-Erkennung hinzugefügt, um die Aktion beim Tippen zu schließen, anstatt die Zelle auszuwählen.

Wie in den Kommentaren angefordert, finden Sie hier ein Gif, wie dies funktioniert (wobei die Farben der Schaltflächen auf der Seite als Hinweis auf eine Aktion angezeigt werden. Sie können jedoch den Rahmen von contentView leicht ändern, um die Schaltflächen in Ihrer Unterklasse vollständig zu überlappen. )

 enter image description here

//
//  MWSwipeableTableViewCell.Swift
//  MW UI Toolkit
//
//  Created by Jan Greve on 02.12.14.
//  Copyright (c) 2014 Markenwerk GmbH. All rights reserved.
//

import UIKit

protocol MWSwipeableTableViewCellDelegate : NSObjectProtocol {
  func swipeableTableViewCellDidRecognizeSwipe(cell : MWSwipeableTableViewCell)
  func swipeableTableViewCellDidTapLeftButton(cell : MWSwipeableTableViewCell)
  func swipeableTableViewCellDidTapRightButton(cell : MWSwipeableTableViewCell)
}

class MWSwipeableTableViewCell: UITableViewCell {
  weak var delegate : MWSwipeableTableViewCellDelegate?
  var animationOptions : UIViewAnimationOptions = [.AllowUserInteraction, .BeginFromCurrentState]
  var animationDuration : NSTimeInterval = 0.5
  var animationDelay : NSTimeInterval = 0
  var animationSpingDamping : CGFloat = 0.5
  var animationInitialVelocity : CGFloat = 1
  private weak var leftWidthConstraint : NSLayoutConstraint!
  private weak var rightWidthConstraint : NSLayoutConstraint!
  var buttonWidth :CGFloat = 80 {
    didSet(val) {
      if let r = self.rightWidthConstraint {
        r.constant = self.buttonWidth
      }
      if let l = self.leftWidthConstraint {
        l.constant = self.buttonWidth
      }
    }
  }
  private weak var panRecognizer : UIPanGestureRecognizer!
  private weak var buttonCancelTap : UITapGestureRecognizer!

  private var beginPoint : CGPoint = CGPointZero
  weak var rightButton : UIButton! {
    willSet(val) {
      if let r = self.rightButton {
        r.removeFromSuperview()
      }
      if let b = val {
        self.addSubview(b)
        b.addTarget(self, action: "didTapButton:", forControlEvents: .TouchUpInside)
        b.translatesAutoresizingMaskIntoConstraints = false
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-(0)-[v]-(0)-|", options: [], metrics: nil, views: ["v":b]))
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("[v]-(0)-|", options: [], metrics: nil, views: ["v":b]))
        let wc = NSLayoutConstraint(item: b, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: self.buttonWidth)
        b.addConstraint(wc)
        self.rightWidthConstraint = wc
        self.sendSubviewToBack(b)
      }
    }
  }
  weak var leftButton : UIButton! {
    willSet(val) {
      if let l = self.leftButton {
        l.removeFromSuperview()
      }
      if let b = val {
        self.addSubview(b)
        b.addTarget(self, action: "didTapButton:", forControlEvents: .TouchUpInside)
        b.translatesAutoresizingMaskIntoConstraints = false
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-(0)-[v]-(0)-|", options: [], metrics: nil, views: ["v":b]))
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-(0)-[v]", options: [], metrics: nil, views: ["v":b]))
        let wc = NSLayoutConstraint(item: b, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: self.buttonWidth)
        b.addConstraint(wc)
        self.leftWidthConstraint = wc
        self.sendSubviewToBack(b)
      }
    }
  }

  override func awakeFromNib() {
    super.awakeFromNib()
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    commonInit()
  }

  override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    commonInit()
  }

  private func commonInit() {

    let pan = UIPanGestureRecognizer(target: self, action: "didPan:")
    pan.delegate = self
    self.addGestureRecognizer(pan)
    self.panRecognizer = pan

    let tap = UITapGestureRecognizer(target: self, action: "didTap:")
    tap.delegate = self
    self.addGestureRecognizer(tap)
    self.buttonCancelTap = tap

    self.contentView.backgroundColor = UIColor.clearColor()
  }


  override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
    if let tap = gestureRecognizer as? UITapGestureRecognizer {
      if tap == self.buttonCancelTap {
                return self.contentView.frame.Origin.x != 0
        }
      else {
        return super.gestureRecognizerShouldBegin(gestureRecognizer)
      }
    }
    else if let pan = gestureRecognizer as? UIPanGestureRecognizer {
      let trans = pan.translationInView(self)
      if abs(trans.x) > abs(trans.y) {
        return true
      }
      else if self.contentView.frame.Origin.x != 0 {
        return true
      }
      else {
        return false
      }
    }
    else {
      return super.gestureRecognizerShouldBegin(gestureRecognizer)
    }
  }


  func didTap(sender : UITapGestureRecognizer) {
    UIView.animateWithDuration(self.animationDuration, delay: self.animationDelay, usingSpringWithDamping: self.animationSpingDamping, initialSpringVelocity: self.animationInitialVelocity, options: self.animationOptions, animations: { () -> Void in
      self.contentView.frame.Origin.x = 0
      }, completion: nil)
  }

  func didPan(sender: UIPanGestureRecognizer) {
    switch sender.state {
    case .Began:
        self.delegate?.swipeableTableViewCellDidRecognizeSwipe(self)
      self.beginPoint = sender.locationInView(self)
      self.beginPoint.x -= self.contentView.frame.Origin.x

    case .Changed:
      let now = sender.locationInView(self)
      let distX = now.x - self.beginPoint.x
      if distX <= 0 {
        let d = max(distX,-(self.contentView.frame.size.width-self.buttonWidth))
        if d > -self.buttonWidth*2 || self.rightButton != nil || self.contentView.frame.Origin.x > 0 {
          self.contentView.frame.Origin.x = d
        }
        else {
          sender.enabled = false
          sender.enabled = true
        }
      }
      else {
        let d = min(distX,self.contentView.frame.size.width-self.buttonWidth)
        if d < self.buttonWidth*2 || self.leftButton != nil || self.contentView.frame.Origin.x < 0 {
          self.contentView.frame.Origin.x = d
        }
        else {
          sender.enabled = false
          sender.enabled = true
        }
      }

    default:
        delegate?.swipeableTableViewCellDidRecognizeSwipe(self)
      let offset = self.contentView.frame.Origin.x
      if offset > self.buttonWidth && self.leftButton != nil {
        UIView.animateWithDuration(self.animationDuration, delay: self.animationDelay, usingSpringWithDamping: self.animationSpingDamping, initialSpringVelocity: self.animationInitialVelocity, options: self.animationOptions, animations: { () -> Void in
          self.contentView.frame.Origin.x = self.buttonWidth
          }, completion: nil)
      }
      else if -offset > self.buttonWidth && self.rightButton != nil {
        UIView.animateWithDuration(self.animationDuration, delay: self.animationDelay, usingSpringWithDamping: self.animationSpingDamping, initialSpringVelocity: self.animationInitialVelocity, options: self.animationOptions, animations: { () -> Void in
          self.contentView.frame.Origin.x = -self.buttonWidth
          }, completion: nil)
      }
      else {
        UIView.animateWithDuration(self.animationDuration, delay: self.animationDelay, usingSpringWithDamping: self.animationSpingDamping, initialSpringVelocity: self.animationInitialVelocity, options: self.animationOptions, animations: { () -> Void in
          self.contentView.frame.Origin.x = 0
          }, completion: nil)
      }
    }
    }

  func closeButtonsIfShown(animated:Bool = true) -> Bool {
    if self.contentView.frame.Origin.x != 0 {
      if animated {
        UIView.animateWithDuration(self.animationDuration, delay: self.animationDelay, usingSpringWithDamping: self.animationSpingDamping, initialSpringVelocity: self.animationInitialVelocity, options: self.animationOptions, animations: { () -> Void in
          self.contentView.frame.Origin.x = 0
          self.panRecognizer.enabled = false
          self.panRecognizer.enabled = true
          }, completion: nil)
      }
      else {
        self.contentView.frame.Origin.x = 0
        self.panRecognizer.enabled = false
        self.panRecognizer.enabled = true

      }
      return true
    }
    else {
      return false
    }
  }

  func didTapButton(sender:UIButton!) {
    if let d = delegate {
      if let l = self.leftButton {
        if sender == l {
          d.swipeableTableViewCellDidTapLeftButton(self)
        }
      }
      if let r = self.rightButton {
        if sender == r {
          d.swipeableTableViewCellDidTapRightButton(self)
        }
      }
    }
    self.closeButtonsIfShown(false)
  }

  override func setHighlighted(highlighted: Bool, animated: Bool) {
    let showing = self.contentView.frame.Origin.x != 0
    if !showing {
      super.setHighlighted(highlighted, animated: animated)
      self.rightButton?.alpha = showing || !highlighted ? 1 : 0
      self.leftButton?.alpha = showing || !highlighted ? 1 : 0
    }
  }

  override func setSelected(selected: Bool, animated: Bool) {
    let showing = self.contentView.frame.Origin.x != 0
    if !showing {
      super.setSelected(selected, animated: animated)
      self.rightButton?.alpha = showing || !selected ? 1 : 0
      self.leftButton?.alpha = showing || !selected ? 1 : 0
    }
  }
}
18
Tobi Nary

Es gibt viele Möglichkeiten, dies zu tun. Sie können in eine der vielen vorhandenen Bibliotheken wie BMXSwipeableCell von Massimiliano Bigatti https://github.com/mbigatti/BMXSwipableCell schauen, wo Sie entweder den Quellcode betrachten können oder kopiere es komplett.

Ein weiterer Ansatz ist das Lesen einer der folgenden zwei großartigen Tutorials:

So erstellen Sie eine swipeable TableViewCell mit Aktionen - ohne gehende Muttern ScrollViews - von Ellen Shapiro: https://www.raywenderlich.com/62435/make-swipeable-table-view-cell-actions -ohne verrückte Bildlauf-Ansichten

So erstellen Sie eine gestengesteuerte To-Do-Liste wie in Swift - von Audrey Tam: https://www.raywenderlich.com/77974/making-a-gesture-driven-to-do -list-app-like-clear-in-Swift-part-1

Um Ihnen eine schnelle Vorstellung zu geben, lautet der Gist wie folgt:

ich. Erstellen Sie eine benutzerdefinierte TableViewCell

ii. UIPangestureRecognizer hinzufügen

iii. Behalten Sie einen Verweis auf dem ursprünglichen contentView-Rahmen bei, dies ist erforderlich, da Sie diese contentView nach links und rechts bewegen (schwenken). Halten Sie einen Verweis auf das OriginalCenter der Zelle. 

iv. Fügen Sie der Zelle die Bilder, Schaltflächen oder anderen Ansichten hinzu, die Sie anzeigen möchten 

Was passiert, ist, dass Sie das Erscheinungsbild Ihrer zuschaltbaren Zelle durch die drei Stufen der UIPanGestureRecognizer führen: UIGestureStateBegan, UIGestureStateChanged, UIGestureStateEnded

  1. UIGestureStateBegan: Prüfen Sie zunächst, ob es sich um eine horizontale Verschiebung und nicht um eine vertikale Verschiebung in der UIGestureDelegate handelt. Wir machen dies, um die UITableView nicht zu verwechseln, da Sie sich vielleicht erinnern, vertikal zu scrollen. Dann erhalten Sie einen Verweis auf das ursprüngliche Zentrum der Zelle.

  2. UIGestureStateChanged: Wenn ein Benutzer seinen Finger nach links oder rechts bewegt, müssen wir das Erscheinungsbild der Zelle aktualisieren. Durch Verschieben des contentView's-Mittelpunkts der Zelle unter Verwendung der ursprünglichen Mittelpunktsreferenz und der Bewegung, die uns durch die Geste gegeben wird, erhalten wir genau das Verhalten, das wir erreichen möchten.

  3. UIGestureStateEnded: Hier müssen wir entscheiden, ob wir das enthüllte Bild, die Schaltfläche usw. nach dem Freigeben der Zelle in Sicht behalten möchten oder ob wir zurückschnappen wollen. Der Schwellenwert dafür ist wirklich bis zu, wird jedoch eine prozentuale Änderung nach links oder rechts sein, verglichen mit der Gesamtbreite der Zelle. Wenn Sie zurückschnappen möchten, setzen Sie einfach den Frame der contentView auf den ursprünglichen Frame, auf den wir einen Verweis gehalten haben. Ist dies nicht der Fall, stellen Sie einen Versatz ein, der den Inhalt, den Sie anzeigen möchten, schön darstellt.

Ich hoffe, dass dies dazu beigetragen hat, dass das Konzept vermittelt wird. Bitte lesen Sie eines der beiden erstaunlichen Tutorials für eine detailliertere Erklärung!

4
trdavidson

Mit der Swipe-Gestenerkennung konnte ich dasselbe Ergebnis erzielen. Hoffe das würde helfen.

  1. Erstellen Sie eine Tabelle mit einer Prototypzelle.
  2. Schaltfläche "Hinzufügen" auf der linken und rechten Seite der Zelle mit Bild für den Standardsteuerungsstatus (Sie können das Bild basierend auf dem Statussteuerungsstatus ändern).
  3. Fügen Sie eine Containeransicht (hier ist MainView) über der Zelle hinzu, die den gesamten Zellbereich abdeckt.
  4. Erstellen Sie eine TableViewCustomCell durch Unterklasse der UITableViewCell
  5. Ändern Sie die Klasse der Prototypzelle in die benutzerdefinierte Variable TableViewCustomCell.
  6. Verwenden Sie den folgenden Code in TableViewCustomCell

SWIFT-Code :

    import UIKit

    class TableViewCustomCell:UITableViewCell {

    @IBOutlet weak var rightButton: UIButton!
    @IBOutlet weak var leftButton: UIButton!
    @IBOutlet weak var mainView: UIView!
    @IBAction func leftButtonTap(sender: AnyObject) {
        print("leftTap")
    }

    @IBAction func rightButtonTap(sender: AnyObject) {
         print("rightTap")
    }

    override func awakeFromNib() {
        let leftSwipe = UISwipeGestureRecognizer(target: self, action:Selector("swipe:"))
        leftSwipe.direction = .Left;
        self.mainView.addGestureRecognizer(leftSwipe)

        let rightSwipe = UISwipeGestureRecognizer(target: self, action:Selector("swipe:"))
        rightSwipe.direction = .Right;
        self.mainView.addGestureRecognizer(rightSwipe)
    }

    func swipe(sender:AnyObject)
    {
        let swipeGesture:UISwipeGestureRecognizer = sender as! UISwipeGestureRecognizer
        if(swipeGesture.direction == .Left)
        {
            var frame:CGRect = self.mainView.frame;
            frame.Origin.x = -self.leftButton.frame.width;
            self.mainView.frame = frame;
        }
        else if(swipeGesture.direction == .Right)
        {
            var frame:CGRect = self.mainView.frame;
            frame.Origin.x = +self.rightButton.frame.width;
            self.mainView.frame = frame;
        }

    }
}
4
Ronald

Wenn Sie die Bibliothek für eine solche Funktion verwenden möchten, würde ich vorschlagen, https://github.com/MortimerGoro/MGSwipeTableCell ... zu verwenden.

es ist einfach zu bedienen und einfach anzupassen.

1
Dev_Tandel

Die allgemeine Idee ist einfach: Die Inhaltsansicht Ihres Zellen ist eine UIScrollView mit Ansichten auf den Seiten.

Die komplette Arbeitslösung ist jedoch etwas kompliziert und wahrscheinlich zu breit für eine Antwort.

Ich würde Ihnen empfehlen, mit einer bereits implementierten Lösung zu beginnen, z. SWTableViewCell (aber es gibt andere) und schauen Sie in den Quellcode. Oder nutzen Sie es einfach direkt. Die meisten Lösungen können mit cocoapods installiert werden und funktionieren sowohl in Swift als auch in Objective-C.

0
Sulthan