El parámetro userInteractionEnabled se propaga a todas las subviews. Es decir, si aplicamos a un UIView este parámetro, ninguna de sus subvistas responderán a interacciones por parte del usuario.

On iOS, if a superview’s userInteractionEnabled is NO, then all subviews are disabled as well?

Tampoco funciona si creas una subclase de UIView y sobrescribimos el método tal que así.

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
		return false
}

No obstante sí que es posible usar ese mismo método y marcar zonas de la UIView que capturen el toque, y marcar zonas que no; las que no capturan el toque serán las que devuelvan false al punto point que se pasa por parámetro, y si queremos capturar el toque, devolveremos true.

Atención: el método point(inside:…) se llama siempre, no solo al tocar dentro de la vista en cuestión. Tiene sentido: es el método que, efectivamente, evalúa si hemos tocado dentro de la vista, como su propia cabecera indica. Hay que asegurarse de llamar al método super.point(inside:…) como condición, y ejecutar nuestra lógica únicamente cuando este método devuelva true. Se me ocurre:

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
		guard super.point(inside: point, with: event) == true else {
				return false // super.point(inside:…) returned false, so we return it too
		}
		// Do our shit
}