Die Situation, die ich versuchte, bestand darin, ein Control Panel mit Steuerelementen in verschachtelten UIStackViews zu erstellen. Einige der Steuerelemente hatten UITextFields andere mit UIButton. Es gab auch Etiketten zur Identifizierung der Kontrollen. Was ich tun wollte, war, eine große „unsichtbare“ Schaltfläche hinter das Bedienfeld zu setzen, damit ich, wenn ein Benutzer auf einen Bereich außerhalb einer Schaltfläche oder eines Textfelds tippte, diese abfangen und Maßnahmen ergreifen konnte - in erster Linie jede Tastatur, wenn ein Text vorhanden war Feld war aktiv (resignFirstResponder). Wenn Sie jedoch auf ein Etikett oder einen anderen leeren Bereich im Bedienfeld tippen, werden die Dinge nicht durchgelassen. Die obigen Diskussionen waren hilfreich, um meine Antwort unten zu finden.
Grundsätzlich habe ich UIStackView unterklassifiziert und die Routine „point (inside: with)“ überschrieben, um nach der Art der Steuerelemente zu suchen, die berührt werden müssen, und Dinge wie Beschriftungen, die ich ignorieren wollte, zu „ignorieren“. Es wird auch nach UIStackViews gesucht, damit die Dinge in die Systemsteuerungsstruktur zurückkehren können.
Der Code ist vielleicht etwas ausführlicher als er sein sollte. Aber es war beim Debuggen hilfreich und bietet hoffentlich mehr Klarheit darüber, was die Routine tut. Stellen Sie im Interface Builder sicher, dass Sie die Klasse der UIStackViews in PassThruStack ändern.
class PassThruStack: UIStackView {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
for view in self.subviews {
if !view.isHidden {
let isStack = view is UIStackView
let isButton = view is UIButton
let isText = view is UITextField
if isStack || isButton || isText {
let pointInside = view.point(inside: self.convert(point, to: view), with: event)
if pointInside {
return true
}
}
}
}
return false
}
}}