A situação que eu estava tentando fazer era criar um painel de controle usando controles dentro do UIStackView aninhado. Alguns dos controles tinham outros UITextField com UIButton. Além disso, havia rótulos para identificar os controles. O que eu queria fazer era colocar um grande botão "invisível" atrás do painel de controle, para que, se um usuário tocasse em uma área fora de um botão ou campo de texto, ele pudesse capturá-lo e tomar uma ação - principalmente descartar qualquer teclado se um texto O campo estava ativo (resignFirstResponder). No entanto, tocar em uma etiqueta ou outra área em branco no painel de controle não passaria nada. As discussões acima foram úteis para apresentar minha resposta abaixo.
Basicamente, classifiquei o UIStackView e substitui a rotina "point (inside: with) para procurar o tipo de controle que precisava do toque e" ignorar "coisas como etiquetas que eu queria ignorar. Ele também verifica se há dentro do UIStackView, para que as coisas possam voltar à estrutura do painel de controle.
O código é talvez um pouco mais detalhado do que deveria ser. Mas foi útil na depuração e, esperançosamente, fornece mais clareza no que a rotina está fazendo. Apenas certifique-se de que no Interface Builder altere a classe do UIStackView para PassThruStack.
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
}
}