Giter Club home page Giter Club logo

joystick's Introduction

CI COV License: MIT

👋 Hey! Check out the Quake3-iOS repo (and others) by tomkidd. He used this code for the movement control. Badge of honor 🏅 (or 🦡 of honor).

Joystick

A custom UIView in Swift that presents a simple joystick interface. The custom view consists of two UIImageView instances, one for the base and one for the handle. When the user moves the handle, it will report out a value based on its position in relation to the joystick base. The type of information reported depends on the type of monitor installed:

  • JoyStickViewMonitorKind.polar -- reports out instances of JoyStickViewPolarReport with
    • angle -- the direction the handle is point, given in degrees, where north/up is 0° and east/right is 90°
    • displacement -- the distance from the center the handle moved, from 0.0 to 1.0 with 1.0.
  • JoyStickViewMonitorKind.xy -- reports out instances of JoyStickViewXYReport with
    • x -- horizontal offset from the center of the base, where east/right is positive
    • y -- vertical offset from the center of the base, where north/up is positive
let monitor: JoyStickViewPolarMonitor = {
    print("\(String(format: "%.2f°", $0.angle)) \(String(format: "%.3f", $0.displacement))")
}

joystick.monitor = .polar(monitor: monitor2)

There is also support (since 3.0.1) for using an Objective-C block as a monitor, with a slight reduction in type safety. The setPolarMonitor and setXYMonitor both take a closure that accepts two CGFloat arguments and returns no value. Objective-C blocks can be used as well as Swift closures in these methods. Since 3.1.0, there is also a tappedBlock attribute which one can use to receive a notification when the user just taps on the joystick handle.

The view supports an option (movable) where the view will move when the user moves the handle to a displacement beyond 1.0. This can be useful when the initial position of the joystick in an app is not ideal for the user's thumb. Double-tapping on the joystick moves it back to its original position.

In the animation above, there are two joysticks, one green and one magenta. The green is fixed and does not move even when the touch motion would cause a displacement larger than 1.0. The magenta joystick however is movable, with the base following the touch motion. For movable joysticks, the Base motion is optionally restricted to a CGRect in the movableBounds property, as is the case in the demonstration animation above where the magenta joystick cannot move out of the pink band.

Additional Properties

Here are some additional configurable features of the JoyStickView:

  • handleConstraint -- optional CGRect which constrains where the handle can move. See the playground for an example.
  • baseImage -- a UIImage to use for the base of the joystick.
  • handleImage -- a UIImage to use for the handle of the joystick.
  • baseAlpha -- opacity of the base of the joystick.
  • handleAlpha -- opacity of the handle of the joystick.
  • handleTintColor -- optional tint color applied to the joystick image.
  • handleSizeRatio -- scaling applied to the joystick handle's image. Note that default is 0.85 due to historical reasons.
  • enableDoubleTapForFrameReset -- if movable is true, allow user to double-tap on view to move base to original location.
  • handlePositionMode -- when set to .absolute (default) the handle will move to the initial (constrained) press location. When set to .relative the handle will move only after the touch moves.

Releases

  • v3.2.0 -- Offer code as Swift package in addition to CocoaPod packaging
  • v3.1.1 -- Added handlePositionMode property to control how handle movements are reported. Default behavior is .absolute. New .relative mode offers finer control at initial touch (thanks to Michael Tyson)
  • v3.1.0 -- Added tappedBlock property (thanks to Michael Tyson)
  • v3.0.2 -- Fixed too much scaling in scaleHandleImageView
  • v3.0.1 -- Added support for Obj-C monitor blocks
  • v3.0.0 -- Swift 5 (no code changes, only Xcode configury)
  • v2.1.2 -- Swift 4.2

Code

The Xcode workspace contains three components:

Both the playground and the app rely on the framework for the JoyStickView UIView.

⚠️ NOTE: due to the plumbing for CocoaPods, when editing in Xcode open the workspace JoyStickView.xcworkspace instead of the project JoyStickView.xcodeproj.

The Xcode playground code sets up the display environemnt and installs two joysticks, one that is fixed (green) and the other that is movable (yellow). Both joysticks report out their positions in two labels, one for angles and the other for displacement.

The JoyStickView.swift file defines the joystick view and behavior. It resides inside the JoyStickView Swift package, and in the BRHJoyStickView framework in CocoaPods. There you will also find a file called CoreGraphics+Additions.swift that contains various extensions to some CoreGraphics structs that allow for some simplified mathematical expressions in the JoyStickView code.

By default the JoyStickView class uses two image assets found in the Assets container. folder:

  • DefaultBase — the image to use for the base of the joystick
  • DefaultHandle — the image to use for the handle of the joystick. Note: this will be tinted with the handleTintColor setting

Both exist in three resolutions for the various iOS devices out today. They were generated using the great Opacity app. The Opacity documents are included in this repository in the Resources directory for the JoyStickViewApp demonstration app.

To use your own images, simple set baseImage and/or handleImage attributes with the UIImage you wish to use.

Documentation

Please see the code documentation for additional information.

CocoaPods

There is a simple CocoaPods spec file available so you can add the code and resources by adding "BRHJoyStickView" to your Podfile file and import with import BRHJoyStickView. Currently everything more or less works, except for the fact that pointing to image resources via Interface Builder (IB) will result in invalid UImage results because the files won't be found where IB was able to find them. The only solution is to manually locate those files and set them in your view loading code. Something like the following should help:

extension Bundle {

    /**
     Locate an inner Bundle generated from CocoaPod packaging.

     - parameter name: the name of the inner resource bundle. This should match the "s.resource_bundle" key or
       one of the "s.resoruce_bundles" keys from the podspec file that defines the CocoPod.
     - returns: the resource Bundle or `self` if resource bundle was not found
    */
    func podResource(name: String) -> Bundle {
        guard let bundleUrl = self.url(forResource: name, withExtension: "bundle") else { return self }
        return Bundle(url: bundleUrl) ?? self
    }
}

In your setup code, you then will need to do something like so:

    override func viewDidLoad() {
        super.viewDidLoad()
        let bundle = Bundle(for: JoyStickView.self).podResource(name: "BRHJoyStickView")
        joystick.baseImage = UIImage(named: "FancyBase", in: bundle, compatibleWith: nil)
        joystick.handleImage = UIImage(named: "FancyHandle", in: bundle, compatibleWith: nil)
    }

The podResource method attempts to locate a named inner bundle, defaulting to the original bundle if not found. The viewDidLoad code will then use the right bundle object in the UIImage constructors.

joystick's People

Contributors

bradhowes avatar michaeltyson avatar neomantra avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

joystick's Issues

Does not have sandbox access for frZQaeyWLUvLjeuEK43hmg and IS NOT appropriately entitled

Hi! I meet a issue when I Created a JoyStickView.

Here is the comment:

2017-08-21 11:42:46.201525+0800 JoyStick[498:223604] libMobileGestalt MobileGestaltSupport.m:153: pid 498 (JoyStick) does not have sandbox access for frZQaeyWLUvLjeuEK43hmg and IS NOT appropriately entitled
2017-08-21 11:42:46.201665+0800 JoyStick[498:223604] libMobileGestalt MobileGestalt.c:550: no access to InverseDeviceID (see rdar://problem/11744455)

I used Xcode 8.3.3 & iOS 10.3, please help for this issue. Many thanks!

Stop handle from cancelling too easily?

I'm noticing that if I move too quickly, the handle very easily cancels and returns to its home position. I have to wait a moment (around 0.5 seconds) to get the handle to stay with my thumb as I move it. My application doesn't require the user to hold the joystick at all times, so it gets a bit frustrating having to re-grab, and wait, for the handle.
Is there a way to make this more tolerant—i.e., something I can tweak to make it harder for the handle to cancel like this? Thanks!

How to add direction arrow image at edge the joystick circle image and its should rotate arrow image as per joystick direction

How to add direction arrow image at edge of the joystick circle image and its should rotate image as per joystick direction.

When joystick button is at centre, direction arrow image at corner should be transparent ..when its moves or reach to corner or edge of the circle,direction arrow image its should appears from transparent to normal ...same like below image effect..

Can you please give me some idea or suggestion how to achieve this..

Screen Shot 2020-11-12 at 4 03 35 PM

The handleConstraint feature to limit joystick movement appears to be broken

I cannot limit the joystick's movement using the 'handleConstraint' property. I am using version 3.2.0 of the release. This is reproducible using the included JoyStickView Playground without any modification. Slide the "Constrain Movement" switch to On and observe that movement is not restricted.

I am using Xcode 14.3.1 with an iOS deployment target of 12.0. Am I doing something wrong? Without any luck, I've tried changing the 'handlePositionMode' between 'absolute' and 'relative'. Has something changed?

3 Issues I wanted to ask you

#1 Can i touch both joystick simultaneously?
Since i have no iOS device, i haven't tested on iOS device. Only see that is working on simulator in
the Xcode... Do you know it is working if i press both joystick at the same time?

#2 Moving both joystick with pressing exterior area
I think pulling the base from interior circle is also a great but i want to try moving base pressing
external area from joystick... Can you have any suggestions like adding more code for pressing
external area to draw joysticks or revising the current source?

#3 References for your project
Thank you again for sharing this code on github! Can you share me about the references for
creating this wonderful joystick? I am really new to coregraphic framework... so it was really helpful
with your comment to understand your code but it would be great if you add references while you
are creating your projects! Thank you very much!

How to use this library in Objective-c

I can able to load and drag joystick in objective-c but iam not able to getting angle and displacement value..
How can i access below method in objective-c.

let monitor: JoyStickViewPolarMonitor = {
print("(String(format: "%.2f°", $0.angle)) (String(format: "%.3f", $0.displacement))")
}

joystick.monitor = .polar(monitor: monitor2)

Handle movement just in one axis?

Hi,
is it possible to enable movement for handle just in one axis? For example to just move in y-axis (up and down) like in this image:
Screenshot 2019-03-22 at 09 33 04
Thanks

Support for Swift Package manager?

Hi, thanks for your nice library. This is just a suggestion as I'm relatively new to Swift I find the Swift Package manager very convenient so I was just wondering if you could add support for that? If this is something you don't want to offer feel free to close this :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.