На самом деле, это действительно серьезная проблема, поскольку UIScrollView "ест" TouchesMoved события (даже если распространяет несколько первых).
Итак, я только что придумал способ получать события непосредственно из UIWindow. Это, конечно, не лучший подход с точки зрения структуры приложения, но в некоторых нестандартных ситуациях (что было именно то, что мне было нужно) это нормально.
(Примеры приведены на MonoTouch C #).
Создайте свой настраиваемый UIWindow (я не показываю здесь, как заменить стандартный UIWindow на MyWindow из-за моей настраиваемой логики (с использованием структуры MvvmCross), но это довольно просто и обычно выполняется в логике инициализации appDelegate - вы будете найдите это в Google / stack overflow):
public class MyWindow : UIWindow
{
public MyWindow(RectangleF bounds) : base(bounds)
{
}
public override void SendEvent(UIEvent evt)
{
if (evt.Type == UIEventType.Touches) {
var el = (UITouch)evt.AllTouches.AnyObject;
if (el.Phase == UITouchPhase.Began)
{
if(OnTouchBegan != null)
OnTouchBegan(el.View, new TouchCommandArgs(evt.AllTouches, evt));
}
if (el.Phase == UITouchPhase.Moved)
{
if(OnTouchMoved != null)
OnTouchMoved(el.View, new TouchCommandArgs(evt.AllTouches, evt));
}
if (el.Phase == UITouchPhase.Ended)
{
if(OnTouchEnd != null)
OnTouchEnd(el.View, new TouchCommandArgs(evt.AllTouches, evt));
}
if (el.Phase == UITouchPhase.Cancelled)
{
if(OnTouchCancel != null)
OnTouchCancel(el.View, new TouchCommandArgs(evt.AllTouches, evt));
}
} else
MvxTrace.Trace (evt.Type == null ? "-" : evt.ToString ());
base.SendEvent(evt);
}
public event TouchCommand OnTouchBegan;
public event TouchCommand OnTouchEnd;
public event TouchCommand OnTouchCancel;
public event TouchCommand OnTouchMoved;
}
public class TouchCommandArgs : EventArgs
{
public NSSet Touches { get; set; }
public UIEvent Evt { get; set; }
public TouchCommandArgs(NSSet touches, UIEvent evt)
{
Touches = touches;
Evt = evt;
}
}
а в месте обработки событий подпишитесь на пользовательские обработчики событий:
var window = (MyWindow) UIApplication.SharedApplication.KeyWindow;
window.OnTouchBegan += view_OnTouchBegan;
window.OnTouchMoved += view_OnTouchMoved;
window.OnTouchCancel += view_OnTouchCancel;
window.OnTouchEnd += view_OnTouchEnd;
такие обработчики, как (это все ваше собственное):
void view_OnTouchBegan(object sender, TouchCommandArgs args)
{
// do your logic
}
В этом случае события будут обрабатываться одновременно (в обоих местах: в вашем и в UIScrollView), поэтому дополнительно, если вы хотите, вы можете отменить распространение событий окна, только если вы хотите предотвратить применение любых других обработчиков, кроме вашего (вы можете добавить " Например, обработанный флаг для ваших обработчиков).
person
Agat
schedule
01.08.2013