ios - Pasando toques entre UIWindows apilados?
uiview touch (3)
En lugar de utilizar múltiples UIWindows, obtenga la ventana de la clave con [ [UIApplication sharedApplication] keyWindow ], luego agregue su vista:
mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview:view]
Tengo dos ventanas, una delantera y una trasera. La frontal se usa para superponer algunas cosas sobre la trasera. Quiero poder capturar toques en algunas partes de la ventana frontal, pero no en otras; Quiero que la ventana frontal reciba toques en algunas áreas, pero páselos a la ventana trasera en otras.
¿Alguna idea de cómo haría esto?
Ok, esto es lo que hice: creé dos vistas en la ventana frontal. La primera vista cubrió el área donde quería captar los toques; El segundo, donde quería que pasaran los toques. Sub-clasifiqué UIWindow y anulé el método hitTest: withEvent así:
- (UIView *) hitTest:(CGPoint)point withEvent:(UIEvent *)event {
// See if the hit is anywhere in our view hierarchy
UIView *hitTestResult = [super hitTest:point withEvent:event];
// ABKSlideupHostOverlay view covers the pass-through touch area. It''s recognized
// by class, here, because the window doesn''t have a pointer to the actual view object.
if ([hitTestResult isKindOfClass:[ABKSlideupHostOverlayView class]]) {
// Returning nil means this window''s hierachy doesn''t handle this event. Consequently,
// the event will be passed to the host window.
return nil;
}
return hitTestResult;
}
Y en la clase que crea la ventana frontal, utilicé un reconocedor de gestos para detectar los toques en la primera vista.
Lo mismo en el código 2017:
class PassView: UIView {}
class UIHigherWindow: UIWindow {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
if hitView!.isKind(of: PassView.self) {
return nil
}
return hitView
}
}
Su ventana "uber" será un controlador de vista, UberVc.
Simplemente haga la vista principal (es decir, simplemente la vista de fondo) de UberVc sea un PassView.
A continuación, agregue botones de decir, etc. en el UberVc.
El código anterior da como resultado cualquier clic en los botones que van a UberVc, y cualquier clic que no se haga en los botones (es decir, en el "fondo") que van a su ventana / VC regular.
Tuve un problema similar: el UIWindow adicional debería tener una vista transparente sobre él con algunas subvistas intratables. Todos los toques fuera de esas vistas intratables deben ser pasados.
Terminé usando la versión modificada del código de Anna que usa la etiqueta de vista en lugar de la verificación de tipos. De esta manera no se requiere la creación de subclases de vista:
class PassTroughWindow: UIWindow {
var passTroughTag: Int?
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
if let passTroughTag = passTroughTag {
if passTroughTag == hitView?.tag {
return nil
}
}
return hitView
}
}
Suponiendo que tiene una ventana y un controlador de vista raíz creado, podría usarlo así:
let window: PassTroughWindow
//Create or obtain window
let passTroughTag = 42
window.rootViewController.view.tag = passTroughTag
window.passTroughTag = passTroughTag
//Or with a view:
let untouchableView: UIView // Create it
untouchableView.tag = passTroughTag
window.addSubview(untouchableView)