A better way to handle gestures on iOS

Related tags

Gesture Tactile
Overview

Travis Status CocoaPods compatible Carthage compatible

Tactile is a safer and more idiomatic way to respond to gestures and control events. It lets you catch bugs at compile time and write more expressive code.

view.pan([
    .began:   panBegan,
    .changed: panChanged,
    .ended:   panEnded
])

// func panBegan(pan: UIPanGestureRecognizer)
// func panChanged(pan: UIPanGestureRecognizer)
// func panEnded(pan: UIPanGestureRecognizer)

Usage β€’ Installation β€’ License

Usage

Tactile extends both UIView and UIControl classes.

UIView extensions

UIView+Tactile.swift

The on method

Use the on method to add gesture recognizers.

on(gesture:callback:)

let tap = UITapGestureRecognizer()
tap.numberOfTapsRequired = 3
tap.numberOfTouchesRequired = 2

view.on(tap, tapped)

// func tapped(tap: UITapGestureRecognizer)

on(gesture:state:callback:)

let pinch = UIPinchGestureRecognizer()

view.on(pinch, .began, pinchBegan)

// func pinchBegan(pinch: UIPinchGestureRecognizer)

on(gesture:states:callback:)

let pan = UIPanGestureRecognizer()

view.on(pan, [.began, .ended], panBeganOrEnded)

// func panBeganOrEnded(pan: UIPanGestureRecognizer)

on(gesture:callbacks:)

let pinch = UIPinchGestureRecognizer()

view.on(pinch, [
  .began: pinchBegan,
  .ended: pinchEnded
])

// func pinchBegan(pinch: UIPinchGestureRecognizer)
// func pinchEnded(pinch: UIPinchGestureRecognizer)

The shorthand methods

Tactile defines 6 shorthand methods: longPress, pan, pinch, rotation, swipe and tap.

<shorthand>(callback:)

view.tap(tapped)

// func tapped(tap: UITapGestureRecognizer)

<shorthand>(state:callback:)

view.pinch(.began, pinchBegan)

// func pinchBegan(pinch: UIPinchGestureRecognizer)

<shorthand>(states:callback:)

view.pan([.began, .ended], panBeganOrEnded)

// func panBeganOrEnded(pan: UIPanGestureRecognizer)

<shorthand>(callbacks:)

view.longPress([
  .began: longPressBegan,
  .ended: longPressEnded
])

// func longPressBegan(longPress: UILongPressGestureRecognizer)
// func longPressEnded(longPress: UILongPressGestureRecognizer)

The off method

Use the off method to remove gesture recognizers.

off(gesture:)

let tap = UITapGestureRecognizer()
view.on(tap, tapped)

// ...

view.off(tap)

off(gestureType:)

view.off(UITapGestureRecognizer.self)

off()

view.off()

Attaching a gesture recognizer to multiple views

With Tactile, you can attach the same gesture recognizer to multiple views.

let tap = UITapGestureRecognizer()
tap.numberOfTapsRequired = 3
tap.numberOfTouchesRequired = 2

firstView.on(tap, firstViewTapped)
secondView.on(tap, secondViewTapped)

UIControl extensions

UIControl+Tactile.swift

Use the on method to attach an event handler function for one or more control events.

on(event:callback:)

button.on(.touchUpInside, tapped)

// func tapped(button: UIButton)

on(events:callback:)

button.on([.touchUpInside, .touchUpOutside], tapped)

// func tapped(button: UIButton)

on(callbacks:)

button.on([
  .touchUpInside: tapped,
  .touchUpOutside: cancelledTap
])

// func tapped(button: UIButton)
// func cancelledTap(button: UIButton)

Installation

Carthage

Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate Tactile into your Xcode project using Carthage, specify it in your Cartfile:

github "delba/Tactile" >= 1.0

CocoaPods

CocoaPods is a dependency manager for Cocoa projects.

You can install it with the following command:

$ gem install cocoapods

To integrate Tactile into your Xcode project using CocoaPods, specify it in your Podfile:

use_frameworks!

pod 'Tactile', '~> 1.0'

License

Copyright (c) 2015-2019 Damien (http://delba.io)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

You might also like...
The easiest way to handle a simple full screen activity indicator in iOS. Written in Swift.
The easiest way to handle a simple full screen activity indicator in iOS. Written in Swift.

LLSpinner An easy way to handle full screen activity indicator. Easy to use Get Started // Show spinner LLSpinner.spin() // Hide spinner LLSpinner.st

Handle in-app purchases in iOS in a convenient way

InAppPurchases Handle in-app purchases in iOS in a convenient way. Overview InAppPurchases covers all the basic aspects of in-app purchases in swift i

A splendid route-matching, block-based way to handle your deep links.
A splendid route-matching, block-based way to handle your deep links.

DeepLink Kit Overview DeepLink Kit is a splendid route-matching, block-based way to handle your deep links. Rather than decide how to format your URLs

A simple way to handle dependency injection using property wrappers

Injektion Introduction A simple way to handle dependency injection using propert

Simple and elegant way to handle UIAlertController.
Simple and elegant way to handle UIAlertController.

SwiftyAlert SwiftAlert is simple and elegant way to handle UIAlertController. Feature Handle action with async/await Method chain Support UITextField

Examples projects using SwiftUI released by WWDC2019. Include Layout, UI, Animations, Gestures, Draw and Data.
Examples projects using SwiftUI released by WWDC2019. Include Layout, UI, Animations, Gestures, Draw and Data.

SwiftUI Examples About Examples projects using SwiftUI & Combine. Include Layout, UI, Animations, Gestures, Draw and Data. See projects files in Files

RxSwift reactive wrapper for view gestures
RxSwift reactive wrapper for view gestures

RxGesture Usage To run the example project, clone the repo, in the Example folder open RxGesture.xcworkspace. You might need to run pod install from t

BabySortingToyGame - Build a little game for babies to sort shapes in the correct location. This is made in SwiftUI using drag gestures.
BabySortingToyGame - Build a little game for babies to sort shapes in the correct location. This is made in SwiftUI using drag gestures.

This is a demo to build a little mini-game "for babies". It's inspired in this kind of games:

GesturesSwiftUI - A simple project to demonstrate how gestures works in SwiftUI

GesturesSwiftUI - A simple project to demonstrate how gestures works in SwiftUI

Easily use ARKit to detect facial gestures.
Easily use ARKit to detect facial gestures.

Easily use ARKit to detect facial gestures. FaceTrigger is a simple to use class that hides the details of using ARKit's ARSCNView to recognize facial gestures via ARFaceAnchor.BlendShapeLocations

A better way to operate QR Code in Swift, support iOS, macOS, watchOS and tvOS.
A better way to operate QR Code in Swift, support iOS, macOS, watchOS and tvOS.

EFQRCode is a lightweight, pure-Swift library for generating stylized QRCode images with watermark or icon, and for recognizing QRCode from images, in

A better way to operate QR Code in Swift, support iOS, macOS, watchOS and tvOS.
A better way to operate QR Code in Swift, support iOS, macOS, watchOS and tvOS.

EFQRCode is a lightweight, pure-Swift library for generating stylized QRCode images with watermark or icon, and for recognizing QRCode from images, in

A better way to operate QR Code in Swift, support iOS, macOS, watchOS and tvOS.
A better way to operate QR Code in Swift, support iOS, macOS, watchOS and tvOS.

EFQRCode is a lightweight, pure-Swift library for generating stylized QRCode images with watermark or icon, and for recognizing QRCode from images, in

πŸš€ Create XCFrameworks with ease! A Command Line Tool to create XCFramework for multiple platforms at one shot! The better way to deal with XCFrameworks for iOS, Mac Catalyst, tvOS, macOS, and watchOS.
πŸš€ Create XCFrameworks with ease! A Command Line Tool to create XCFramework for multiple platforms at one shot! The better way to deal with XCFrameworks for iOS, Mac Catalyst, tvOS, macOS, and watchOS.

Surmagic πŸš€ Create XCFramework with ease! A Command Line Tool to create XCFramework for multiple platforms at one shot! The better way to deal with XC

A better way to operate QR Code in Swift, support iOS, macOS, watchOS and tvOS.
A better way to operate QR Code in Swift, support iOS, macOS, watchOS and tvOS.

EFQRCode is a lightweight, pure-Swift library for generating stylized QRCode images with watermark or icon, and for recognizing QRCode from images, in

A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI.
A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI.

BetterSafariView A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI. Contents Motivation Requirements U

A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI
A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI

A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI.

The better way to deal with JSON in Objective-C (inspired by SwiftyJSON)

NSTEasyJSON Inpired by SwiftyJSON. NSTEasyJSON makes it easy to deal with JSON data in Objective-C. Why is the typical JSON handling in Objective-C NO

Protocol oriented, Cocoa UI abstractions based library that helps to handle view controllers composition, navigation and deep linking tasks in the iOS application. Can be used as the universal replacement for the Coordinator pattern.
Comments
  • Using Tactile with UIControl works inconsistently

    Using Tactile with UIControl works inconsistently

    I like the concept very much, unfortunately Tactile isnt reliable. When using it as so:

    let button = UIButton()
    button.on(.TouchUpInside, functionToCall)
    

    it only works about 95% of the time for me and my colleagues on different projects.

    I had a quick look and would like to point you to this piece of code:

    116 private let proxies = NSMapTable.weakToStrongObjectsMapTable()
    117 
    118 private class Proxy: NSObject {
    119     var actor: Triggerable!
    120     
    121     init(actor: Triggerable, control: UIControl, event: UIControlEvents) {
    122         super.init()
    123         
    124         self.actor = actor
    125         
    126         proxies.setObject(self, forKey: "\(control, event.rawValue)")
    127     }
    128     
    129     @objc func recognized(control: UIControl) {
    130         actor.trigger(control)
    131     }
    132 }
    

    You are using a weakToStrongObjectsMapTable(), which has the property that: "Use of weak-to-strong map tables is not recommended. The strong values for weak keys which get zeroed out continue to be maintained until the map table resizes itself." I think that the key "\(control, event.rawValue)" goes out of scope immediately, then, whenever the mapTable is resized, the values are released and stop working.

    Also suspicious to me is the cycle Actor<--owns-->Proxy.

    Can you please take a look at this and explain? Thanks

    opened by pteasima 6
  • Block support

    Block support

    Hello,

    first, very nice work indeed. What would help this project to be really great is if the methods offered block version instead of target. That way you would be able to do following:

    view.on(tap) {
        // Do something
    }
    

    Which removes the decoupling - the need to have different method somewhere else in the code.

    Thanks for your time doing this library!

    Sincerely, Jiri

    opened by JiriTrecak 3
Owner
Damien
Damien
Special way to work with gestures in iOS

At a Glance Sensitive is a library that simplifies work with gestures in iOS. Forget about target/action pattern of primitive UIGestureRecognizer. Wit

Igor M. 550 Dec 29, 2022
Special way to work with gestures in iOS

At a Glance Sensitive is a library that simplifies work with gestures in iOS. Forget about target/action pattern of primitive UIGestureRecognizer. Wit

Igor M. 550 Dec 29, 2022
Best way to use UIGesture

NiceGesture The best way to use UIGesture #Usage ###TapGesture: because tapGesture is only have one state,so it's only have method whenTapped view.n

Zhuo 104 Sep 9, 2022
Gesture recognizer tool [Swift / iOS]

DBPathRecognizer Demo Installation Simply add the file DBPathRecognizer.swift to your project Basic usage Start by creating a new DBPathRecognizer ins

Didier Brun 1.2k Dec 18, 2022
Drag and drop between your apps in split view mode on iOS 9

SplitViewDragAndDrop Easily add drag and drop to pass data between your apps Setup Add pod 'SplitViewDragAndDrop' to your Podfile or copy the "SplitVi

Mario Iannotta 324 Nov 22, 2022
The easiest way to show off your iOS taps and gestures for demos and videos.

It's ShowTime ?? Installation Swift Package Manager Cocoapods Manual Usage How it works Useful info Author License ShowTime is the simplest and best w

Kane Cheshire 459 Dec 27, 2022
Special way to work with gestures in iOS

At a Glance Sensitive is a library that simplifies work with gestures in iOS. Forget about target/action pattern of primitive UIGestureRecognizer. Wit

Igor M. 550 Dec 29, 2022
Special way to work with gestures in iOS

At a Glance Sensitive is a library that simplifies work with gestures in iOS. Forget about target/action pattern of primitive UIGestureRecognizer. Wit

Igor M. 550 Dec 29, 2022
🎯Linker Lightweight way to handle internal and external deeplinks in Swift for iOS

Linker Lightweight way to handle internal and external deeplinks in Swift for iOS. Installation Dependency Managers CocoaPods CocoaPods is a dependenc

Maksim Kurpa 128 May 20, 2021
An easier way to handle third-party URL schemes in iOS apps.

IntentKit ========= IntentKit is an easier way to handle third-party URL schemes in iOS apps. Linking to third-party apps is essentially broken on iOS

null 1.8k Dec 24, 2022