Sie können eine computed property
zu Ihrer Erweiterung hinzufügen, die Sie in Ihrem Controller einstellen können, wenn Sie die Hit-Bereich wie folgt aktivieren möchten:
fileprivate let minimumHitArea = CGSize(width: 100, height: 100)
extension UIButton {
var isIncreasedHitAreaEnabled: Bool {
get {
// default value is false, so you can easily handle from outside when to enable the increased hit area of your specific button
return false
}
set {
}
}
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
// if the button is hidden/disabled/transparent it can't be hit
if self.isHidden || !self.isUserInteractionEnabled || self.alpha < 0.01 { return nil }
// only if it's true the hit area can be increased
if isIncreasedHitAreaEnabled {
// increase the hit frame to be at least as big as `minimumHitArea`
let buttonSize = self.bounds.size
let widthToAdd = max(minimumHitArea.width - buttonSize.width, 0)
let heightToAdd = max(minimumHitArea.height - buttonSize.height, 0)
let largerFrame = self.bounds.insetBy(dx: -widthToAdd/2, dy: -heightToAdd/2)
// perform hit test on larger frame
return (largerFrame.contains(point)) ? self : nil
}
return self
}
}
Und dann in Ihrem View-Controller setzen nur isIncreasedHitAreaEnabled
zu true
, wenn Sie wollen sie für eine bestimmte Taste erhöhen (zB in Ihrem viewDidLoad
):
override func viewDidLoad() {
super.viewDidLoad()
specialButton.isIncreasedHitAreaEnabled = true
}
Update:
Zunächst funktioniert die Methode, die Sie verwenden, nicht wie erwartet. Und auch mein Ansatz mit der computed property
funktionierte nicht so, wie ich dachte. Auch wenn die Methode nicht wie erwartet funktioniert, möchte ich nur meinen Ansatz mit der computed property
aktualisieren. Um die Eigenschaft von außerhalb festzulegen, können Sie Associated Objects verwenden. Schauen Sie auch here. Mit dieser Lösung jetzt wäre es möglich, die Bool
Eigenschaft isIncreasedHitAreaEnabled
von dem Controller zu handhaben:
fileprivate let minimumHitArea = CGSize(width: 100, height: 100)
private var xoAssociationKey: UInt8 = 0
extension UIButton {
var isIncreasedHitAreaEnabled: Bool {
get {
return (objc_getAssociatedObject(self, &xoAssociationKey) != nil)
}
set(newValue) {
objc_setAssociatedObject(self, &xoAssociationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
// if the button is hidden/disabled/transparent it can't be hit
if self.isHidden || !self.isUserInteractionEnabled || self.alpha < 0.01 { return nil }
if isIncreasedHitAreaEnabled {
// increase the hit frame to be at least as big as `minimumHitArea`
let buttonSize = self.bounds.size
let widthToAdd = max(minimumHitArea.width - buttonSize.width, 0)
let heightToAdd = max(minimumHitArea.height - buttonSize.height, 0)
let largerFrame = self.bounds.insetBy(dx: -widthToAdd/2, dy: -heightToAdd/2)
// perform hit test on larger frame
return (largerFrame.contains(point)) ? self : nil
}
return self
}
}
Eine Alternative zu @ ronatory's Antwort ist (1) Unterklasse UIButton als, sagen wir, 'SpecialButton', und dann erweitern, dass anstelle von UIButton. – dfd
Beachten Sie, dass das Überschreiben von Funktionen aus einer Erweiterung eine schlechte Idee ist und nicht in "pure" swift, nur in Objective-C NSObject-Klassen zulässig ist. Um das Apple Swift iBook zu zitieren: "Erweiterungen können einem Typ neue Funktionen hinzufügen, aber sie können vorhandene Funktionalität nicht überschreiben." Auszug aus: Apple Inc. "Die Swift-Programmiersprache (Swift 3.0.1)." IBooks. https://itun.es/us/jEUH0.l –
Aktualisierte meine Antwort. Aber leider funktioniert die Methode nicht wie erwartet. Ich denke, dass Sie die Antwort von matt versuchen sollten http://stackoverflow.com/a/42182054/5327882 – ronatory