Skip to content

Instantly share code, notes, and snippets.

@warren-gavin
Last active February 12, 2017 15:12
Show Gist options
  • Save warren-gavin/7a656efee9a923e8f54d9ef09ebafbd1 to your computer and use it in GitHub Desktop.
Save warren-gavin/7a656efee9a923e8f54d9ef09ebafbd1 to your computer and use it in GitHub Desktop.
Code snippets for blog "Touchy-feely"
class Button: UIButton {
private var tappableSurface: UIButton?
override func addTarget(_ target: Any?, action: Selector, for controlEvents: UIControlEvents) {
super.addTarget(target, action: action, for: controlEvents)
if bounds.size.width < .minimumButtonDimension || bounds.size.height < .minimumButtonDimension {
let button = UIButton()
addSubview(button)
sendSubview(toBack: button)
button.translatesAutoresizingMaskIntoConstraints = false
button.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
button.widthAnchor.constraint (equalToConstant: max(bounds.size.width, .minimumButtonDimension)).isActive = true
button.heightAnchor.constraint (equalToConstant: max(bounds.size.height, .minimumButtonDimension)).isActive = true
button.addTarget(target, action: action, for: controlEvents)
tappableSurface = button
}
}
}
private extension CGFloat {
static let minimumButtonDimension: CGFloat = 44.0
}
class Button: UIButton, ExtendedTouchable {
var touchableSurface: UIView?
override func layoutSubviews() {
super.layoutSubviews()
setupTouchableArea()
}
}
protocol ExtendedTouchable: class {
var touchableSurface: UIView? { get set }
func setupTouchableArea()
}
extension ExtendedTouchable where Self: UIControl {
func setupTouchableArea() {
touchableSurface = {
let view = UIView()
view.backgroundColor = .clear
addSubview(view)
sendSubview(toBack: view)
view.translatesAutoresizingMaskIntoConstraints = false
view.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
view.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
view.widthAnchor.constraint (equalToConstant: max(bounds.size.width, .minimumButtonDimension)).isActive = true
view.heightAnchor.constraint (equalToConstant: max(bounds.size.height, .minimumButtonDimension)).isActive = true
return view
}()
}
}
class Button: UIButton, ExtendedTouchable {
var touchableSurface: UIView?
override func layoutSubviews() {
super.layoutSubviews()
setupTouchableArea()
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard let touchableSurface = touchableSurface, touchableSurface.frame.contains(point) else {
return super.hitTest(point, with: event)
}
return self
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment