NSView Mouse Pan and Zoom

I'm completely new to the MacOS development ecosystem and have been recently learning Swift. I'm wanting to create an application that uses a view of some sort to draw 2D lines from a list of geo coordinates (latitude and longitude). My first instinct was to use OpenGL, but being it's now deprecated, I looked into using Metal. Beings that I'm a novice, I don't want to attempt to learn Metal on top of learning Swift, so I opted for an easier approach by using Core Graphics to render these 2D lines. I want to be able to zoom in and out of the view (i.e. change the scale of the objects) as well as pan around the view area because it will be possible that the 2D objects will not all fit within the "visible viewing area" and I want to be able to pan around to be able to show the "hidden objects" that are not within the current view — if that makes sense? I'd like to hear whether this is feasible and what the best approach is to accomplish this...or if there's a better alternative.

Replies

Yes, it is feasible and Core Graphics is good enough to do this.


A way is to apply affineTransform to the UIView.


You may learn from this tutorial:

h ttps://www.raywenderlich.com/5976-uiview-animations-tutorial-practical-recipes


Instance Propertytransform


Specifies the transform applied to the view, relative to the center of its bounds.


Declaration

var transform: CGAffineTransform { get set }

Discussion

Use this property to scale or rotate the view's frame rectangle within its superview's coordinate system. (To change the position of the view, modify the

center
property instead.) The default value of this property is
CGAffineTransformIdentity
.

Transformations occur relative to the view's anchor point. By default, the anchor point is equal to the center point of the frame rectangle. To change the anchor point, modify the

anchorPoint
property of the view's underlying
CALayer
object.

Changes to this property can be animated.

In iOS 8.0 and later, the

transform
property does not affect Auto Layout. Auto layout calculates a view’s alignment rectangle based on its untransformed frame.



If it is for MacOS, use

func scale(CGFloat)

Mutates an affine transformation matrix to perform the given scaling in both x and y dimensions.


func scale(x: CGFloat, y: CGFloat)

Mutates an affine transformation matrix to perform a scaling in each of the x and y dimensions.



It sounds like you should be using MapKit for this.

I considered this, however, I don't need map tiles. Unless there's a way to hide map tiles and only use the canvas for drawing?

You can define custom map tiles if you want. I think there is a WWDC video on this and several other blog tutorials. However, you will also likely get other map artifacts that you might not want.


You should be able to use plain old core graphics for this. Just define a path and stroke it. I don't think you even need affine transformations in macOS. Maybe that is an iOS thing. You should be able to just set the magnification on your scroll view.

Using scale from Core Graphics should do most of what you need.