JoyStickView
@IBDesignable
public final class JoyStickView : UIView
extension JoyStickView: UIGestureRecognizerDelegate
A simple implementation of a joystick interface like those found on classic arcade games. This implementation detects and reports two values when the joystick moves:
- angle: the direction the handle is pointing. Unit is degrees with 0° pointing up (north), and 90° pointing right (east).
- displacement: how far from the view center the joystick is moved in the above direction. It has no units as it is the ratio of distance moved from center over the radius of the joystick base. Always in range 0.0-1.0.
The view has several settable parameters that be used to configure a joystick’s appearance and behavior:
- monitor: an enumeration of type
JoyStickViewMonitorKind
that can hold a function to receive updates when the joystick’s angle and/or displacement values change. Supports polar and cartesian (XY) reporting - movable: a boolean that when true lets the joystick move around in its parent’s view when there joystick moves beyond displacement of 1.0.
- movableBounds: a CGRect which limits where a movable joystick may travel
- baseImage: a UIImage to use for the joystick’s base
- handleImage: a UIImage to use for the joystick’s handle
Additional documentation is available via the attribute names below.
-
Optional monitor which will receive updates as the joystick position changes. Supports polar and cartesian reporting. The function to call with a position report is held in the enumeration value.
Declaration
Swift
public var monitor: JoyStickViewMonitorKind
-
Optional block to be called upon a tap.
Declaration
Swift
public var tappedBlock: (() -> Void)? { get set }
-
Optional rectangular region that restricts where the handle may move. The region should be defined in this view’s coordinates. For instance, to constrain the handle in the Y direction with a UIView of size 100x100, use
CGRect(x: 50, y: 0, width: 1, height: 100)
Declaration
Swift
public var handleConstraint: CGRect? { get set }
-
The last-reported angle from the joystick handle. Unit is degrees, with 0° up (north) and 90° right (east). Note that this assumes that
angleRadians
was calculated with atan2(dx, dy) and that dy is positive when pointing down.Declaration
Swift
public var angle: CGFloat { get }
-
The last-reported displacement from the joystick handle. Dimensionless, it is the ratio of movement over the radius of the joystick base. Always falls between 0.0 and 1.0
Declaration
Swift
public private(set) var displacement: CGFloat { get }
-
If
true
the joystick will move around in the parent’s view so that the joystick handle is always at a displacement of 1.0. This is the default mode of operation. Setting tofalse
will keep the view fixed.Declaration
Swift
@IBInspectable public var movable: Bool
-
The original location of a movable joystick. Used to restore its position when user double-taps on it.
Declaration
Swift
public var movableCenter: CGPoint?
-
Optional rectangular region that restricts where the base may move. The region should be defined in the this view’s coordinates.
Declaration
Swift
public var movableBounds: CGRect? { get set }
-
The opacity of the base of the joystick. Note that this is different than the view’s overall opacity setting. The end result will be a base image with an opacity of
baseAlpha
*view.alpha
Declaration
Swift
@IBInspectable public var baseAlpha: CGFloat { get set }
-
The opacity of the handle of the joystick. Note that this is different than the view’s overall opacity setting. The end result will be a handle image with an opacity of
handleAlpha
*view.alpha
Declaration
Swift
@IBInspectable public var handleAlpha: CGFloat { get set }
-
The tintColor to apply to the handle. Changing it while joystick is visible will update the handle image.
Declaration
Swift
@IBInspectable public var handleTintColor: UIColor? { get set }
-
Scaling factor to apply to the joystick handle. A value of 1.0 will result in no scaling of the image, however the default value is 0.85 due to historical reasons.
Declaration
Swift
@IBInspectable public var handleSizeRatio: CGFloat { get set }
-
Control how the handle image is generated. When this is
false
(default), a CIFilter will be used to tint the handle image with thehandleTintColor
. This results in a monochrome image of just one color, but with lighter and darker areas depending on the original image. When this istrue
, the handle image is just used as a mask, and all pixels with an alpha = 1.0 will be colored with thehandleTintColor
value.Declaration
Swift
@IBInspectable public var colorFillHandleImage: Bool { get set }
-
Controls how far the handle can travel along the radius of the base. A value of 1.0 (default) will let the handle travel the full radius, with maximum travel leaving the center of the handle lying on the circumference of the base. A value greater than 1.0 will let the handle travel beyond the circumference of the base, while a value less than 1.0 will reduce the travel to values within the circumference. Note that regardless of this value, handle movements will always report displacement values between 0.0 and 1.0 inclusive.
Declaration
Swift
@IBInspectable public var travel: CGFloat
-
The image to use for the base of the joystick
Declaration
Swift
@IBInspectable public var baseImage: UIImage? { get set }
-
The image to use for the joystick handle
Declaration
Swift
@IBInspectable public var handleImage: UIImage? { get set }
-
Control whether view will recognize a double-tap gesture and move the joystick base to its original location when it happens. Note that this is only useful if
moveable
is true.Declaration
Swift
@IBInspectable public var enableDoubleTapForFrameReset: Bool { get set }
-
Position mode for a joystick handle. The default (original) is
See moreabsolute
mode.Declaration
Swift
public enum HandlePositionMode
-
How the handle is moved with the initial touch
Declaration
Swift
public var handlePositionMode: HandlePositionMode
-
Minimum distance in either X or Y coordinate the handle must move for
handleHasMoved
to returntrue
.Declaration
Swift
public var handleMovedTolerance: CGFloat
-
The image to use to show the handle of the joystick
Declaration
Swift
internal var handleImageView: UIImageView
-
Initialize new joystick view using the given frame.
Declaration
Swift
public override init(frame: CGRect)
Parameters
frame
the location and size of the joystick
-
Initialize new joystick view from a file.
Declaration
Swift
public required init?(coder: NSCoder)
Parameters
coder
the source of the joystick configuration information
-
A touch began in the joystick view
Declaration
Swift
public override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
Parameters
touches
the set of UITouch instances, one for each touch event
event
additional event info (ignored)
-
An existing touch has moved.
Declaration
Swift
public override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
Parameters
touches
the set of UITouch instances, one for each touch event
event
additional event info (ignored)
-
An existing touch event has been cancelled (probably due to system event such as an alert). Move joystick to center of base.
Declaration
Swift
public override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?)
Parameters
touches
the set of UITouch instances, one for each touch event (ignored)
event
additional event info (ignored)
-
User removed touch from display. Move joystick to center of base.
Declaration
Swift
public override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
Parameters
touches
the set of UITouch instances, one for each touch event (ignored)
event
additional event info (ignored)
-
Reset our base to the initial location before the user moved it. By default, this will take place whenever the user double-taps on the joystick handle.
Declaration
Swift
@objc public func resetFrame()
-
This is the appropriate place to configure our internal views as we have our own geometry.
Declaration
Swift
public override func layoutSubviews()
-
Returns
true
if the handle has moved, where moving means the displacement in either coordinate ishandleMovedTolerance
or greater.Declaration
Swift
public var handleHasMoved: Bool { get }
-
Implementation of gesture recognizer delegate method. Controls whether a gesture recognizer should continue to track events. This is always the case when in absolute mode (original behavior), but in relative mode it is only allowed until the handle has moved a meaningful amount.
Declaration
Swift
public override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool
Parameters
gestureRecognizer
the gesture recognizer being queried
Return Value
true if the gesture recognizer can continue to track events
-
Report the current joystick values to any registered
monitor
.Declaration
Swift
internal func reportPosition()
-
Install an Obj-C block that will receive the polar coordinates of the joystick.
Declaration
Swift
@objc public func setPolarMonitor(_ block: @escaping (CGFloat, CGFloat) -> Void)
Parameters
block
the block to install. It must expect two CGFloat values, first being the angle, and the second being the displacement
-
Install an Obj-C block that will receive the XY unit coordinates of the joystick.
Declaration
Swift
@objc public func setXYMonitor(_ block: @escaping (CGFloat, CGFloat) -> Void)
Parameters
block
the block to install. It must expect two CGFloat values, first being the X unit coordinate, and the second being the Y unit coordinate.