Keyboard shortcut to move map view? - objective-c

I'm trying to implement the same feature, that Maps.app has on OS X, where when selecting the map, the arrow keys on the keyboard moves the map north/south (up/down) and east/west (left/right).
I've created a sample project, added a MKMapView to the storyboard just to ensure that I've not overwritten anything in my 'real' project, but the default behavior is the same, ie. the map is not responding to the keyboad strokes.
I've searched the documentation, looking at the delegate protocols, but have been unable to finde an answer. Any ideas? (It does not matter if its Swift or Objective-C)

So, after a few days thought, I've come to this solution:
Create a function that moves the map (I've used setCenterCoordinate:), and trigger this from keyDown. There is a little regarding zooming and moving the map that need to be thought of though.
I'm leaving this here, in case someone can use it :)

Related

Draggable MapKit Annotations

I am working with MapKit on MacOS and trying to enable a draggable annotation that uses a custom image. I can successfully get the annotation to be draggable but it requires the user to be quite accurate with where they click and drag as the annotation image is larger than a conventional pin. Is there a simple way to expand the area so that any part of the image is draggable? Otherwise I imagine I will have to use some kind of NSGesture on the view to manually set the dragstate, but was hoping there might be an easier way!
Okay, I never managed to sort this to my satisfaction using Annotations. I’m not saying it can’t be done, maybe someone else can comment and leave pointers to help. But I eventually achieved what I wanted using overlays instead. So if someone stumbles on this question and has the same issue, you can make it work with a custom overlay rather than an annotation and you implement the dragging using a NSPanGestureRecognizer with translation for the movement.

NSCollectionViewItems shaking and with X to remove

On Launchpad we have basically a big collection view with app icons. When you hold an app (press down with the cursor and don't stop) for a very long time, all the icons start to shake, and a little 'x' appears in the top left hand corner of each one of them, which makes removing items very easy.
I would like to know if there is some method already implemented in the API which allow us to reproduce that same behavior in a regular NSCollectionView.
I've checked NSCollectionView and NSCollectionViewDelegate documentations in Apple's Mac Developer Library, however I haven't seeing anything related to that. Should that be done manually? If so, how can I make the collection view items shake?
There is no existing method to do this, but you can recreate it with Core Animation.
Providing the full code to do that is beyond the scope of Stack Overflow (and would be highly dependent on your existing code), but a CABasicAnimation affecting the transform.rotation key of the layers of your NSCollectionViewItem views should put you on the right path.

NSWindow attached to cursor

I would like to make a custom panel, that shows a zoom at the current cursor-location.
Like for example 'Sip' does.
I have searched the web for examples, but didn't find anything specific.
I found NSEvent's addGlobalMonitorForEventsMatchingMask:handler: and addLocalMonitorForEventsMatchingMask:handler: methods.
Now I could just set the frame origin of the window.
But I'm not sure if that's really the right solution.
Is there a better way to do this?
Could anyone point me into some sample-code?
That's basically it.
You can also use the Quartz Event Tap function family CGEventTap, as it will provide a little more responsiveness during events like the Mac application switcher and Exposé or Mission Control or Dashboard. However, it is a little harder to set up, and uses a C callback approach that is a little tougher to use with some things.
Quartz Event Taps are otherwise the same thing, but possibly slightly faster.
If you use that, be sure to use the function CGPoint CGEventGetUnflippedLocation(CGEventRef aCGEvent)
As in:
CGPoint eventLocation = CGEventGetUnflippedLocation(aCGEvent);
That will make sure your y coordinates are bottom left like the rest of Cocoa.
Otherwise use its sibling CGEventGetLocation() which for some odd reason of crappy naming doesn't indicate that it returns flipped coordinates. (but the docs do state this)

Programmatically resizing NSSplitView

I used to use and love RBSplitView, however I failed at reimplementing it programmatically as a certain version of xcode does not support IB plugins anymore.
Therefore I went back to using NSSplitView. NSSplitView is fine for what I need, the thing is that the autoSave of NSSplitView is broken. So I decided to implement it myself.
The thing I am doing at the moment is resizing 1 of the subviews of the NSSplitView.
What is the proper way of resizing an NSSplitView? - setPositionOfDivider:itIndex: should be the way to go ( haven't tried it ), however I do not know how to get the current position of the divider.
-- thanks in advance
In my experience, NSSplitView hates you and wishes you harm. RBSplitView is so much better, it is worth IMO the headache of programatic layout (and I've been so burned with the ShortcutRecorder IB plugins that I will never go back to IB plugins).
That said....
The only way that I know of to determine the current position of the divider is to look at the subviews, find the divider's view, take it's frame, and work out its position keeping in mind the dividerThickness. It is insane that you have to write that code, but the code isn't that incredibly difficult, and you can put it in a category.
Or go back to RBSplitView while you still can, if your needs are ever going to be complicated.
I'm using Swift here but the same method should exist in Objective C:
mySplitter.setPosition(123, ofDividerAtIndex: 0)

Cocoa: How to morph a drag image while dragging

In Interface Builder.app (and some other cocoa apps), image dragging has a very nice/sexy effect of morphing the drag image while you drag a draggable item out of its window.
For example in Interface Buildler.app:
Show the Library Palette (⇧⌘L, or Tools Menu -> Library)
Drag an item out of the Library palette
NOTE: as you drag the item out of the Library Palette window, it morphs from an image of the original list item to an image of the icon of the dragged item.
I have fully implemented drag and drop in my Application using the normal Cocoa NSDragSource/NSDragDestination facilities.
However, I can't find a hook for doing this image morph while dragging. I'm returning the initial drag image by overriding
-[NSView dragImage:at:offset:event:pasteboard:source:slideBack:]
But this is only called at the beginning of the drag.
How do you signal that you would like to replace the current drag image (ideally using the sexy morph effect).
You guys beat me to it. :-)
Yes, JLNDragEffectManager is open source (with attribution in your apps, please) and available on my blog. It should work fine as-is with no modification back to 10.5, but I'm not sure back any further. Others linked to it (and it's easily googleable), so to avoid self-congratulatory blog linking, I'll leave it at that.
Issues: One developer commented on (and submitted code to fix) the lack of dragging offset support. I've just not gotten around to posting the update. That's the only outstanding issue I'm aware of.
Improvements: I'd like to add multiple "zones" (say, one per document, so dragging from doc to doc keeps table rows looking like table rows, but anywhere outside doc windows turns them into a file icon a la HFS Promise Drag). Some day ...
Design: The post itself details the reasoning behind the design and the relatively simple morphing effect (cross-fade plus size are animated using basic NSAnimation, etc.). The code (the class as well as the demo app) is thoroughly blocked out and commented.
Won't link to my own post but would love the karma of upvotes for my effort. ;-)
UPDATE: Similar (but better-integrated) functionality is available as of 10.7. If you are targeting 10.7 or higher, it's best to use the new API. JLNDragEffectManager works fine on 10.7, so it can be used for earlier-targeted versions.
JNLDragEffectManager does exactly that. :)
The API does not support this well. Joshua Nozzi gives a method that looks reasonable in this weblog post.
IB's effect isn't that fancy. It's a crossfade and scale. Hold down shift to see it more clearly.
As of 10.7+ the current approach is to use the
enumerateDraggingItemsWithOptions:
forView:
classes:
searchOptions:
usingBlock:
API on NSDraggingInfo. The documentation is really poor but the ADC samples like MultiPhotoFrame or TableViewPlayground can give a good idea on how to use the new mechanism.