-
Suggestion
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
5.14.0, 6.5
-
None
Hi, doing my first iOS Qt app, and today I tried swiping some QWidgets on my iPhone. While Qt's swipe gestures work fine on my Mac and Windows 10, on the phone it's really tricky to swipe with 3 fingers. Most apps use 1 finger for swipes, seems to be standard on all phones.
Turns out there's an iOS API for recognizing swipes with 1 finger (also with no churn, been the same for 10 years), and it's pretty trivial to integrate that API with Qt's existing QGesture infrastructure.
I ended up with a small .mm file with a function that I call from my QMainWindow's ctor, that registers Apple's swipe API into Qt's QUIView, and in the callback from iOS I post a matching QSwipeGesture. So now I can swipe my widgets with 1 finger on the phone ![]()
Would it be possible to add this functionality to Qt itself? As I said, it seems pretty easy, here's the function and the Objective-C method I inject into QUIView (you call the function with your QMainWindow's this and the swipe direction you wish to receive an event for):
bool registerForIOSSwipes(QWidget* w, QSwipeGesture::SwipeDirection sd)
{
// cast the widget's winId (it's our ticket into the iOS underworld)
auto uv = reinterpret_cast<UIView*>(w->winId());
// what we really like is a ptr to Qt's UIView (QUIView)
if ("QUIView" != QString::fromNSString(NSStringFromClass([uv class])))
return false; // but it was not to be
// have a view, use a lambda to add the 4 different types of swipe gestures
auto registerSwipe = [uv](UISwipeGestureRecognizerDirection d)
{
// new up an iOS gesture recognizer with required # of touches = 1 (Apple default)
UISwipeGestureRecognizer* sgr = [[UISwipeGestureRecognizer alloc] initWithTarget:uv action:@selector(handleSwipe:)];
[sgr setDirection:d];
[uv addGestureRecognizer:sgr];
};
if (sd & QSwipeGesture::Left )
registerSwipe(UISwipeGestureRecognizerDirectionLeft );
if (sd & QSwipeGesture::Right)
registerSwipe(UISwipeGestureRecognizerDirectionRight);
if (sd & QSwipeGesture::Up )
registerSwipe(UISwipeGestureRecognizerDirectionUp );
if (sd & QSwipeGesture::Down )
registerSwipe(UISwipeGestureRecognizerDirectionDown );
// that's all
return true;
}
// some Objective-C red tape so we can inject our gesture recognizer function into Qt's QUIView
@interface QUIView : UIView @end // (copied from quiview.h)
@implementation QUIView (RedTapeCategory) - (void) handleSwipe: (UISwipeGestureRecognizer*) swipe
{
// got a swipe, synthesize a swipe flavored Qt gesture event and post it
auto sg = new QSwipeGesture;
if (UISwipeGestureRecognizerDirectionLeft == swipe.direction)
sg->setSwipeAngle(180);
if (UISwipeGestureRecognizerDirectionRight == swipe.direction)
sg->setSwipeAngle(0);
if (UISwipeGestureRecognizerDirectionUp == swipe.direction)
sg->setSwipeAngle(90);
if (UISwipeGestureRecognizerDirectionDown == swipe.direction)
sg->setSwipeAngle(270);
auto hotSpot = [swipe locationInView:self];
sg->setHotSpot(QPointF(hotSpot.x,hotSpot.y));
// bon voyage
qApp->postEvent(qApp->activeWindow(),new QGestureEvent(QList<QGesture*>{sg}));
}
@end
Then in my app I receive a normal QSwipeGesture event, say with code like this:
bool MainWindow::event(QEvent *event)
{
if (event->type() != QEvent::Gesture)
return QWidget::event(event);
auto e = static_cast<QGestureEvent*>(event);
auto g = e->gesture(Qt::SwipeGesture);
if (nullptr == g)
return QWidget::event(event);
auto s = static_cast<QSwipeGesture*>(g);
qDebug() << s->hotSpot() << s->horizontalDirection() << s->verticalDirection() << "Z";
return true;
}
(I've trimmed some error checking and skipped the #includes/#imports)
- relates to
-
QTBUG-138601 Swipe gesture does not work on Windows
-
- In Progress
-
-
QTBUG-92086 Add an *Handler way to detect swipe gestures in QtQuick
-
- Reported
-
-
QTBUG-38032 Swipe and pan gestures
-
- Reported
-
-
QTBUG-43650 OS X: try to detect swipe gesture distinctly from mouse wheel
-
- Reported
-
-
QTBUG-51875 Add support for pan and swipe gestures for QtQuick2
-
- Closed
-