Get position of 2nd finger in touch/pinch - xcode

How can I get the position of the 2nd touch in a view in iOS? I am using UITouch and I only know how to get the position of the 1st finger if I am doing a pinch gesture. I am doing the pinch gesture in the simulator via holding the Option Button and dragging on the view.

I don't know if you're using a gesture recognizer or trying to to act on UIResponder.
But in either case the delegate methods are handled an NSSet *touches,
this set can contain more than one object.
So you should enumerate over that set to get all the touches.

Related

Disable Gesture Recognizers in a *subview* so that superview Gesture Recognizers can run

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.

Using infinite scrolling UICollectionView with iOS 13 pullable modals

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?

UIScrollView on tvOS

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)]

NSPageController, deactivate swipe gesture

I'm currently using a NSPageController to navigate between a Master and a Detail View in my OSX Application. I'm basically using it only to support transition animations, since there is no NavigationController on OSX.
However, the default NSPageController is listening on swipe gestures from my magic mouse and trackpad and changes the displayed view on a horizontal swipe. (like going back / forward in your browser). I would like to deactivate this behavior but overriding and intercepting any gesture method in a NSPageController subclass had no effect so far.
It seems like a NSScrollView / NSTableView does absorb these touches since doing a horizontal swipe gesture above any of my TableViews won't result in a view transition. (It only absorbs them for my magic mouse, doing a swipe gesture on my trackpad still results in switching views)
Target OS: Mac OSX 10.9 +
Thanks for your help!
You can make a subclass of NSPageController and overwrite
- (void)scrollWheel:(NSEvent *)theEvent
This should help.

NSPopUpButtonCell inside custom cell does not pop up when clicked

I've created a custom subclass of NSCell with an NSImageCell, some NSTextFieldCells, and an NSPopUpButtonCell.
I'm initializing the pop up cell using:
myPopUpCell = [[NSPopUpButtonCell alloc] init];
[myPopUpCell setBordered:NO];
[myPopUpCell setAutoenablesItems:NO];
[myPopUpCell addItemsWithTitles:[NSArray arrayWithObjects:#"Item1", #"Item2", #"Item3"]];
And drawing it in drawInteriorWithFrame:inView:
Everything seems to work great, except that when clicking on the pop up cell while running my app the cell does not pop up. Any suggestions about what might be wrong?
Drawing the pop-up button cell in drawInteriorWithFrame:inView: is going to do just that; draw it, but nothing else. Handling click events is unrelated to drawing, so you're going to have to do some work in your custom cell to interpret mouse events, and if they're inside the frame you're using for the pop-up button, pass them on to the button cell. Start by subclassing the methods listed in the NSCell docs under tracking the mouse, such as –trackMouse:inRect:ofView:untilMouseUp:, and you should be be able to figure out what's needed to make the button cell act correctly.
Depending on what you're doing you may actually find it easier to draw the title string yourself, and just use NSMenu's +popUpContextMenu:withEvent:forView:.

Resources