2016-07-08 15 views
3

Ich habe eine große UITableViewCell, die 2 benutzerdefinierte UIViews enthält. Eine davon sollte die Interaktion ermöglichen (Auswahl und Abwahl), und eine der Ansichten sollte keine Interaktion zulassen.Verhindern Sie die Interaktion in der Unteransicht von UITableViewCell

Ich weiß, dass ich die Interaktion für die gesamte Zelle oder für jede Unteransicht aktivieren oder deaktivieren kann, aber wenn ich die Interaktion in der UIView deaktiviere, wird die Zelle immer noch ausgewählt oder deaktiviert.

Gibt es eine Möglichkeit, zum Beispiel Berührungen auf der oberen Hälfte der Zelle und nicht auf der Unterseite zuzulassen?

Hier ist ein Screenshot der UITableViewCell I

beschrieben

enter image description here

Antwort

1

Ich stimme völlig mit JAL überein, Sie müssen alle Ihre Zellstruktur überprüfen, aber ich weiß auch, dass manchmal und in einigen Fällen ist es unmöglich Refaktor zu tun.

Also, ich denke, das ist, dass Sie ein CustomTableViewCell von zwei Ansichten zusammengesetzt haben, mit dem Namen zum Beispiel view1 und view2:

Der Code:

class MyView1 : UIView { 
    var isTouched : Bool = false 
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     self.isTouched = true 
     self.nextResponder()?.touchesBegan(touches, withEvent: event) 
    } 
    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     self.isTouched = false 
     self.nextResponder()?.touchesEnded(touches, withEvent: event) 
    } 
} 
class MyView2 : UIView { 
    var isTouched : Bool = false 
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     self.isTouched = true 
     self.nextResponder()?.touchesBegan(touches, withEvent: event) 
    } 
    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     self.isTouched = false 
     self.nextResponder()?.touchesEnded(touches, withEvent: event) 
    } 
} 
class CustomTableViewCell: UITableViewCell { 
    @IBOutlet weak var myExampleLabel: UILabel! 
    @IBOutlet weak var view1: MyView1! 
    @IBOutlet weak var view2: MyView2! 

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     print("situation: myView1 : \(self.view1.isTouched) myView2: \(self.view2.isTouched)") 
     var responder : UIResponder! = self 
     while responder.nextResponder() != nil { 
      responder = responder.nextResponder() 
      if responder is SimpleTableView.ViewController { // the name of your tableView delegate class 
       let vc = responder as! ViewController 
       let indexPath = vc.tableView.indexPathForCell(self) 
       vc.tableView(vc.tableView, didSelectRowAtIndexPath: indexPath!) 
      } 
     } 
     super.touchesBegan(touches, withEvent: event) 
    } 
} 

Auf der anderen Seite, wo Sie zum Beispiel haben eine UIViewController mit einem UITableView:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 
    @IBOutlet var tableView: UITableView! 
    var items: [String] = ["We", "Heart", "Swift", "So", "Much"] 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     tableView.delegate = self 
     tableView.dataSource = self 
     tableView.rowHeight = UITableViewAutomaticDimension 
     tableView.estimatedRowHeight = 140.0 
     self.tableView.registerNib(UINib(nibName: "CustomTableViewCell", bundle:nil), forCellReuseIdentifier: "CustomTableViewCell") 
    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return self.items.count; 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell", forIndexPath: indexPath) as! CustomTableViewCell 
     cell.myExampleLabel.text = self.items[indexPath.row] 
     return cell 
    } 

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
     let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomTableViewCell 
     print("row = %d",indexPath.row) 
     if cell.view1.isTouched { 
      print("tableView: touched view 1") 
      // do whatever you want with cell.view1 
      // if you want you can disable cell.view2.userInteractionEnabled 
     } 
     else { 
      print("tableView: touched view 2") 
      // same thing for cell.view2 
     } 
    } 
} 

Einige wichtige Dinge:

Vergessen Sie nicht die richtige Kundenspezifische Klasse für die beiden Ansichten zu setzen wie in diesem Bild erklärt:

enter image description here

+0

Ein Link zum Herunterladen des Projekts: http://s000.tinyupload.com/?file_id=00948862908688472208 –

0

Sie Berührungen mit Treffertest

override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { 
     if let hitView = super.hitTest(point, withEvent: event) { 
      if hitView.isKindOfClass(CustomSubviewClass) { 
       return nil 
      } else { 
       return hitView 
      } 
     } else { 
      return nil 
     } 
    } 
+0

Sind Sie dies im UITableView oder in einer implementieren was darauf hindeutet, der Unteransichten? Wie auch immer ich es mache es stürzt mit EXC_BAD_ACCESS ab – mattgabor

2

weiterleiten oder stornieren kann ich würde sagen, dass es einen Fehler in der Implementierung ist, oder dass du ein X/Y-Problem hast. Ziehen Sie in Erwägung, die einzelne Zelle in zwei separate Zellen aufzuteilen und die Auswahl in der unteren Zelle zu deaktivieren.

Wenn Sie mit dieser Implementierung fortfahren müssen, sollten Sie die Auswahl für die gesamte Zelle deaktivieren. Fügen Sie in der oberen Teilansicht eine Gestenerkennungsfunktion hinzu, und rufen Sie bei Berührung manuell didSelectRowAtIndexPath: auf.

0

Eine Möglichkeit, dies zu erreichen, besteht darin, die Methoden UITableViewDelegate zu umgehen und IBAction mit einem benutzerdefinierten Rückrufhandler für die Zelle zu verwenden.

  1. die für die Zelle Typ Selection Set-Keine der Zelle aus immer An-/Abwahl zu verhindern, wenn Sie darauf tippen.
  2. Stellen Sie sicher, dass Ihr UITableViewDelegate tableView:didSelectRowAtIndexPath nicht implementiert.
  3. Fügen Sie eine Schaltflächenansicht in die Zelle ein und positionieren Sie sie so, dass sie den Bereich abdeckt, mit dem der Benutzer interagieren soll.
  4. Fügen Sie @IBAction func buttonTapped(sender: UIButton) in der Unterklasse UITableViewCell hinzu.
  5. Fügen Sie der Zelle eine Schließvariable hinzu. Rufen Sie die Schließung auf, wenn Sie auf die Schaltfläche tippen.
  6. Legen Sie in der Delegatenmethode tableView:cellForRowAtIndexPath: die Schließung der Zelle fest, um den Aufruf zu verarbeiten.

Beispiel UITableViewCell Unterklasse:

class MyTableViewCell: UITableViewCell { 

    var selectionHandler: ((Void) -> Void)? 

    override func prepareForReuse() { 
     // Remove the closure when the cell is recycled. 
     selectionHandler = nil 
    } 

    @IBAction func buttonTapped(sender: UIButton) { 
     // Call the closure when the button is tapped. 
     selectionHandler?() 
    } 
} 

In Ihrem UITableViewController:

class MyTableViewController: UITableViewController { 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

     let cell = .... 

     // Set the closure to be called when the button is tapped. 
     // Using weak self here to prevent a retain cycle. 
     cell.selectionHandler = { [weak self] in 
      self?.selectedCellAtIndexPath(indexPath) 
     } 

     return cell 
    } 

    // We are not using didSelectRowAtIndexPath 
    // override func tableView(tableView: UITableView, didSelectRowAtIndexPath: NSIndexPath) { 
    // } 
} 

ich diesen Code nicht getestet haben, damit es nicht kompilieren kann, auch wenn es um das Konzept zu veranschaulichen, dienen soll.

0

Setzen Sie im Tabellenansicht-Eigenschaftseditor Selection Wert auf No Selection oder programmgesteuert. Deaktivieren Sie die Interaktion für jede Unteransicht außer der Unteransicht, für die Sie eine Aktion ausführen möchten. Übergeben Sie den indexPath-Zeilenwert als Tag möglicherweise an diese Unteransicht. Oder Unterklasse dieser Unteransicht von UIView, um IndexPath-Informationen zu speichern.Als nächstes implementieren Sie tippen Geste zu dieser Unteransicht und führen Sie Ihre Wunsch-Aktion auf tippen Geste Erkennung Methode. Hoffe, diese sollten tun, was du willst.