2015-10-13 10 views
13

Ich habe ein UIButton in meinem UITableViewCelliOS Erhöhung Touch-Bereich für UIButton in TableViewCell

ich eine Unterklasse von UIButton Überschreibung der pointInside Funktion gemacht:

var touchMargin:CGFloat = 20.0 

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool { 
    let extendedArea = CGRectInset(self.bounds, -touchMargin, -touchMargin) 
    return CGRectContainsPoint(extendedArea, point) 
} 

jedoch die Berührungsfläche nicht erhöht bekommt.
Ich bekomme eine Berührung auf der Tischzelle, wenn ich etwas außerhalb der UIButton berühre.

Funktioniert dieser Code nicht, weil der Button in einer Zelle platziert ist?
Wie kann ich reparieren?

+2

erhöhen Sie die Breite/Höhe der Schaltfläche, wenn es kein Problem gibt. Was sind die anderen Teilansichten der Zelle? –

Antwort

5

sollten Sie hitTest in der Ansicht überschreiben, die Sie vergrößern möchten.

z.B.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { 
    if (!self.isUserInteractionEnabled || self.isHidden || self.alpha <= 0.01) { 
     return nil; 
    } 
    CGRect touchRect = CGRectInset(self.bounds, -10, -10); 
    if (CGRectContainsPoint(touchRect, point)) { 
     //TODO!? check supviews 
     return self; 
    } 
    return nil; 
} 
9

Swift 3

// 
// ViewController.swift 
// test 
// 
// Created by David Seek on 9/29/16. 
// Copyright © 2016 David Seek. All rights reserved. 
// 

import UIKit 

class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let button = MyButton(frame: CGRect(x: 200, y: 200, width: 100, height: 100)) 
     button.backgroundColor = UIColor.white 
     button.addedTouchArea = 50 // any value you want 
     button.addTarget(self, action:#selector(self.action), for: .touchUpInside) 
     self.view.addSubview(button) 
    } 

    func action() { 
     print("touched") 
    } 

} 

class MyButton: UIButton { 
    var addedTouchArea = CGFloat(0) 

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 

     let newBound = CGRect(
      x: self.bounds.origin.x - addedTouchArea, 
      y: self.bounds.origin.y - addedTouchArea, 
      width: self.bounds.width + 2 * addedTouchArea, 
      height: self.bounds.width + 2 * addedTouchArea 
     ) 
     return newBound.contains(point) 
    } 
} 

Sie sind ein UIButton in der Größe von 100x100 zu schaffen und mit .addedTouchArea, haben Sie eine UIButton - noch optische Größe 100x100, aber mit einem Touch-Bereich von 150x150 .

Swift 2.X

class MyButton: UIButton { 
    var addedTouchArea = CGFloat(0) 

    override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool { 

     let newBound = CGRect(
      x: self.bounds.origin.x - addedTouchArea, 
      y: self.bounds.origin.y - addedTouchArea, 
      width: self.bounds.width + 2 * addedTouchArea, 
      height: self.bounds.width + 2 * addedTouchArea 
     ) 
     return newBound.contains(point) 
    } 
} 

Interface

Wenn Sie den Button mit dem InterfaceBuilder gesetzt haben, unsere Unterklasse von UIButton auf Ihre Schaltfläche anzuwenden.

enter image description here

gesetzt dann einen Zugang zum Knopf, F.E. benannte SchaltflächeXY. Und setzen buttonXY.addedTouchArea = 50 innerhalb viewDidLoad, f.E.

UITableViewCell

Da Sie für UITableViewCell sind gefragt. Es funktioniert genau so.

In Ihrem Viewcontroller Klasse:

extension ViewController: UITableViewDelegate, UITableViewDataSource { 

    func numberOfSections(in tableView: UITableView) -> Int { 
     return 1 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return 1 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell") as! TableViewCell 
     cell.selectionStyle = UITableViewCellSelectionStyle.none 

     cell.myButton.addedTouchArea = 50 // any value you want 
     tableView.rowHeight = 200 

     return cell 
    } 
} 

In Ihr Handy Klasse:

Das einzige, was Sie passen sollte: Der Ausgang als UIButton Auslass eingestellt wurde, sogar tho ich erklärt hatte, es als Unterklasse von MyButton innerhalb der InterfaceBuilder. Ich musste die Steckdose manuell auf MyButton umstellen!@IBOutlet weak var myButton: MyButton!

+0

Wird die Tabellenansicht nicht ausgewählt, wenn Sie auf die Zelle tippen, wenn Sie didSelectRowAtIndexPath festgelegt haben. – user694688

+0

Nein. Ich habe es in einem großen Projekt von mir sowie in einem Projekt JUST WIE DIES verwendet, um es hier für Sie zu testen. Wenn Sie die Schaltfläche drücken, wird didSelectRowAtIndexPath nicht ausgelöst. wenn Sie die Zelle anders als den Trefferbereich der Schaltfläche treffen, wird didSelectRowAtIndexPath - natürlich - ausgelöst –

+0

@ user694688 irgendwelche Nachrichten auf Ihrer Seite? –

0

Zuerst müssen Sie UIButton Unterklasse erstellen:

class ButtonWithTouchSize: UIButton { 

    var touchAreaPadding: UIEdgeInsets? = nil 

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 
     if let inset = touchAreaPadding { 
      let origin = CGPoint(x: 0 - inset.left, y: 0 - inset.top) 
      let size = CGSize(width: inset.left + bounds.width + inset.right, 
           height: inset.top + bounds.height + inset.bottom) 
      let rect = CGRect(origin: origin, size: size) 
      return rect.contains(point) 
     } else { 
      return super.point(inside: point, with: event) 
     } 
    } 
} 

Wenn Sie setzen eine Instanz von ButtonWithTouchSize direkt in UITableViewCell content, Sie bekommen es. Aber wenn man diese Instanz in einem gewissen Behälter Wich wickeln ist in UITableViewCell content, Ihr sollte auch seine Stelle außer Kraft setzen (innen: mit) Methode:

class ContainerView: UIView { 

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 
     return btn.point(inside: point, with: event) 
    } 

    override func layoutSubviews() { 
     super.layoutSubviews() 
     btn.frame = self.bounds 
    } 

    private let btn: ButtonWithTouchSize = ButtonWithTouchSize() 

} 

Also, um es zusammenzufassen ... Sie sollten Punkt außer Kraft setzen (innen: mit) für jede Superansicht, die Größe ist kleiner als die Größe der Tasten

Verwandte Themen