2015-10-13 3 views
13

У меня есть UIButton в моем UITableViewCellIOS увеличение площади касания для UIButton в TableViewCell

Я сделал подкласс UIButton переопределения функции pointInside:

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) 
} 

Однако сенсорная область не получает увеличивается.
Я прикоснусь к ячейке таблицы, если слегка коснувшись UIButton.

Этот код не работает из-за того, что кнопка находится в ячейке?
Как я могу исправить?

+2

увеличить ширину/высоту кнопки, если нет проблем. Каковы другие подвид ячейки? –

ответ

5

вы должны переопределить hitTest на вид, который вы хотите увеличить.

например.

- (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) 
    } 
} 

Вы создаете UIButton размером 100x100, и с .addedTouchArea, у вас есть UIButton - еще оптический размер 100x100, но с сенсорным площадью 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) 
    } 
} 

InterfaceBuilder

Если вы сделали установить кнопку с InterfaceBuilder, применить наш подкласс UIButton к кнопке.

enter image description here

Затем установите выход на кнопку, F.E. named buttonXY. И установите buttonXY.addedTouchArea = 50 в пределах viewDidLoad, f.e.

UITableViewCell

Поскольку вы просите UITableViewCell. Он работает точно так же.

В вашем ViewController классе:

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 
    } 
} 

В классе Cell:

Единственное, что вы должны остерегаться: Выпускной был установлен как UIButton розетку, даже Тхо я объявил это как подкласс MyButton в пределах InterfaceBuilder. Мне пришлось вручную менять розетку до MyButton!@IBOutlet weak var myButton: MyButton!

+0

Будет ли табличное представление не принимать выделение, когда вы нажимаете на ячейку, когда вы установили didSelectRowAtIndexPath. – user694688

+0

Нет. Я использовал его в большом проекте, а также в проекте JUST LIKE THIS, чтобы проверить его здесь для вас. Если вы нажмете кнопку, didSelectRowAtIndexPath не будет запущен. если вы нажмете на ячейку, отличную от области нажатия кнопки, то didSelectRowAtIndexPath будет - конечно, - активировать –

+0

@ user694688 любые новости на вашей стороне? –

0

Прежде всего, необходимо создать подкласс UIButton:

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) 
     } 
    } 
} 

Если поместить экземпляр ButtonWithTouchSize непосредственно в UITableViewCell contentView, вы получите его. Но если вы заключаете этот экземпляр в какой-то контейнер Wich в UITableViewCell contentView, вам следует переопределить свою точку (внутри: с) метод:

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() 

} 

Таким образом, чтобы подвести итог ... вы должны переопределить точку (внутри: с) для каждого супервизора, размер которого меньшеThanOrEqual до размера кнопки

Смежные вопросы