I have a scrollview that has a bindable stacklayout inside it with a Item template that is using the drag and drop gesture recognizer. This works no problem but on android the drag gesture recognizer fires off immediately as soon as you start scrolling the screen. I'm curious if anyone has any ideas on how to handle keeping the gesture recognizer but also allow for the user to scroll the screen without dragging around an item in the list.
Related
I have an NSView (the canvas), into which I'm dropping a set of TextView subclasses (small boxes). The TextView classes have GestureRecognizers on them for drag drop (move) and select.
The canvas has two modes:
drawing
text
In text mode, I can interact with the TextView classes - I can click on them, edit etc.
When I switch to drawing mode, I want to disable the TextView boxes completely, and have all events/gestures be captured by the Canvas.
That way I can do Pan/Click events on the whole of the canvas, and the TextView boxes should be visible but otherwise ignored/disabled.
To enter drawing mode I disable the TextView boxes as follows (if the boolean "drawing" is true, then I turn off all event handling in the TextView boxes):
foreach (var tv in textBoxes)
{
tv.Editable = !drawing;
tv.Selectable = !drawing;
#if __IOS__
tv.UserInteractionEnabled = !drawing;
#else
tv.AcceptsTouchEvents = !drawing;
#endif
foreach (var g in tv.GestureRecognizers)
g.Enabled = !drawing;
}
So everything works perfectly between the two modes on iOS. On the Mac everything mostly work with one exception: in drawing mode (when the textview and textview gestures are disabled) if I start a gesture on top of the TextView box, nothing happens. Neither the Canvas gesture handler NOR the TextView box gesture handler are called. Starting a gesture anywhere else works fine and the Canvas gesture handler receives it.
In summary, my question is: how can I completely disable gestures in a subview, such that the superview gesture will be recognised, even if the gesture starts on top of the subview.
There are samples of handing a gesture to a subview, but here I want to hand a gesture to a superview (which should be top of the responder chain I thought).
Any advice would be gratefully accepted.
It seems that the solution is to ensure that the subview you want to receive gestures has to be at the top, otherwise gestures dont seem to reach it (this means it has to be the last item in the Subviews array).
In other words, if another subview "A" sits above your subview "B" - and that subview "A" is completely disabled with no gesture recognisers... it will stop any gestures in "B" from being recognised.
Gesture recognisers are not supposed to use the responder chain... (that is made clear in UIGestureRecognizer specs, but not NSGestureRecognizer specs). Here is a quote from the latter:
Events received by your app are forwarded automatically to any
relevant gesture recognizers before they are sent to the corresponding
view
This doesn't talk about how events flow up the responder chain for gesture recognisers on the Mac.
So as mentioned above - bring your subview to the front to ensure its gestures will be recognised. With the Mac, there is no way to easily order subviews of NSView (unlike UIView which has bringToFront, sendToBack etc). So the best way I have found is to use SortSubviews, with an appropriate ordering function.
I have a modal window, which is perfect for iOS 13's drag to dismiss gesture, because this way the user remains in the context, so I don't want to use full screen. The controller contains a UICollectionView which displays a month calendar, which is scrollable vertically.
The problem is, that when the user wants to scroll upwards in the collection view, the dismiss gesture is triggered instead. If I scroll down first, then can I only scroll up.
I've tried to disable the internal UIPanGestureRecognizer (it seems somehow there is no presentedView, so it didn't work), tried to set the UICollectionView's pan gesture recognizer delegate to prevent the system recognizer to fire (it turned out you can't do that), and tried to scroll the collection view on appearing a bit (ugly).
How can I elegantly convince the the modal presentation, that my scrollview isn't scrolled to the top?
The question is very simple, how to enable scroll and zoom inside a UIScrollView in tvOS?
I tried the same initializer code from iOS and returned the scrollview for the focusedView var, but nothing happens when i touch the remote.
Also, i tried to add another custom UIPanGestureRecognizer to the scrollview and actually it works, but i don't want to handle the pan with custom code, just use the same pan behavior like iOS.
Let me know, thanks.
You can configure the scroll view's built-in pan gesture to recognize touches on the Siri Remote. It doesn't do that automatically, because normally scroll views on tvOS aren't scrolled directly by touches: they're scrolled automatically as focus moves between views within the scroll view.
If you really want the scroll view to move directly from touches, you'll need to add UITouchTypeIndirect to the allowedTouchTypes of the scroll view's panGestureRecognizer:
scrollView.panGestureRecognizer.allowedTouchTypes = #[ #(UITouchTypeIndirect) ];
You'll also need to make sure that either the scroll view itself is the focused view, or is a parent of the focused view, since all touches from the remote will start at the center of the focused view: you need to make sure the scroll view is getting hit-tested for the events to work.
Zooming won't work, because the Siri Remote can only recognize one touch at a time, so you can't do a pinch gesture on it.
Swift 4 version (from here: https://stackoverflow.com/a/41000183/945247)
scrollView.panGestureRecognizer.allowedTouchTypes = [NSNumber(value:UITouchType.indirect.rawValue)]
So I have a view with attached Pan and Magnify gesture recognisers in a view controller.
When I present the view controller using the Show, Modal or Presentation segues, both gesture recognisers work fine. But when I present it as a Sheet, only the Pan recogniser responds to input. The Magnify recogniser simply doesn't fire at all.
Sample project here. Use the buttons in the first window to show the view controller in different methods, and gesture anywhere in the presented view. The indicators will show which gestures have been recognised.
I'm trying to scroll a textview programmatically using the scrollToPoint method. This works fine if the textview has a scrollbar, but if I disable it with setHasVerticalScroller:NO, I get some strange results: if I try to scroll using the two-finger gesture after the programmatic scroll, the textview automatically jumps back to the point that was shown before the programmatic scroll. I already tried redrawing the textview and actualizing it, but nothing worked.