Protocols for your every day iOS needs

Overview

Standard Template Protocols

Essential protocols for your every day iOS needs

language MIT License Platform

Example

UIGestureRecognizerProtocols

About

Swift 2.0 opens a world of opportunity with enhanced Protocols and Protocol Extensions. This library attempts to address some of the most commonly repeated patterns in iOS apps using protocol oriented programming and reduce the need to create deep, complicated subclassing trees.

Why Protocols?

Too often we find ourselves locked into deep and complicated subclassing trees just to factor out common behavior in our apps. This makes our code inflexible, hard to navigate, and contain too many dependencies. Using protocols for common features allows us to create default behavior that is additive without complicated subclassing.

Setup

CocoaPods (recommended)

  1. Make sure you have downloaded and installed cocoapods.
  2. Add pod 'STP', '~> 0.3.0'to your podfile.
  3. Make sure that your podfile includes use_frameworks!
  4. pod install
  5. import STC and let the magic happen!

Manual

  1. Drag and drop the files into your project and build the app. Note you will not get bugfixes, updates, and new releases if you do this. If you want custom features, I reccommend forking this repo.

UIGestureRecognizer Protocols

All too often, we find ourselves subclassing views to allow them to be tappable, moveable, rotatable, and more. These protocols allow you to add these features by simply conforming to a protocol, but still give you the flexible to create custom features and animations.

Moveable

By default, making a view conform to the Movable protocol will attach a UIPanGestureRecognizer and allow the user to tap on the view and drag it around the screen. The default behavior is for the view to only be dragged within its superview. Creating a moveable view is as simple as:

class MyMoveableView : UIView, Moveable {
    init(frame: CGRect) {
        super.init(frame: frame)
        self.makeMoveable()
    }
}

To do an action on start or finish, or use custom logic for movement or animation, implement the appropriate methods in the Moveable protocol.

func didStartMoving()
func didFinishMoving(velocity:CGPoint)
func canMoveToX(x:CGFloat) -> Bool
func canMoveToY(y:CGFloat) -> Bool
func translateCenter(translation:CGPoint, velocity:CGPoint, startPoint:CGPoint, currentPoint:CGPoint) -> CGPoint
func animateToMovedTransform(transform:CGAffineTransform)

Pinchable

By default, making a view conform to the Pinchable protocol will attach a UIPinchGesetureRecognizer and allow the user to pinch and scale a view. Creating a pinchable view is as simple as:

class MyPinchableView : UIView, Pinchable {
    init(frame: CGRect) {
        super.init(frame: frame)
        self.makePinchable()
    }
}

To do an action on start or finish, or create custom transform or animation logic, simply implement the appropriate methods in the Pinchable protocol

func didStartPinching()
func didFinishPinching()
func maximumPinchScale() -> CGFloat
func minimumPinchScale() -> CGFloat
func transformWithScale(scale:CGFloat, lastScale:CGFloat, velocity:CGFloat) -> CGAffineTransform
func animateToPinchedTransform(transform:CGAffineTransform)

Rotatable

By default, making a view conform to the Rotatable protocol will attach a UIRotationGestureRecognizer and allow the user to use two fingers to rotate a view. Creating a rotatable view is as simple as:

class MyRotatableView : UIView, Rotatable {
    init(frame: CGRect) {
        super.init(frame: frame)
        self.makeRotatable()
    }
}

To do an action on start or finish, or create custom transform or animation logic, simply implement the appropriate methods in the Rotatable protocol

func didStartRotating()
func didFinishRotating(velocity:CGFloat)
func minimumRotation() -> CGFloat
func maximumRotation() -> CGFloat
func transformWithRotation(rotation:CGFloat, lastRotation:CGFloat, velocity:CGFloat) -> CGAffineTransform
func animateToRotatedTransform(transform:CGAffineTransform)

Tappable

By default, making a view conform to the Tappable protocol will attach a UILongPressGestureRecognizer and allow the user to tap. It will call the didTap() method and set the alpha of the view to 0.5 on the down state and 1.0 on the up state. Creating a tappable view is as simple as:

class MyTappableView : UIView, Tappable {
    init(frame: CGRect) {
        super.init(frame: frame)
        self.makeTappable()
    }
    
    func didTap() {
         print("tapped!")
    }
}

To do customize the up and down state and/or adjust the minimum press duration and allowable movement, simply implement the appropriate methods in the Tappable protocol.

func didTap()
func didTouchDown()
func didTouchUp()
func minimumPressDuration() -> NSTimeInterval
func allowableMovement() -> CGFloat

Forceable

By default, making a view conform to the Forceable protocol will attach a ForceTouchGestureRecognizer and allow the user to press down with a force. It will call the didForce() method, but doesn't have any default behavior. Creating a forceable view is as simple as:

class ForceView: UIView, Forceable {
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.makeForceable()
    }
}

To do customize the vide on force, simply implement the appropriate methods in the Forceable protocol.

func didStartForcing(force:CGFloat)
func didForce(force:CGFloat, lastForce:CGFloat)
func didFinishForcing(force:CGFloat)

Using Them Together

Because protocols are addative, you can mix and match these protocols to create even more dynamic views. Creating a view that movable, pinchable, rotatable, and tappable is as easy as:

class MyAwesomeView : UIView, Moveable, Rotatable, Pinchable, Tappable {
    init(frame: CGRect) {
        super.init(frame: frame)
        self.makeMoveable()
        self.makeRotatable()
        self.makePinchable()
        self.makeTappable()
    }
}

Contributions

Pull requests are welcome! :) You can also email me or contact me on Twitter if you have any questions, ideas, or just want to contribute.

t: @chrisoneil_

e: [email protected]

A special thanks to jhurray for inspring me to do work on some open source code.

TODO:

There's a ton that we can do here, and I would love to hear suggestions and get pull requets. Here are some things that I'm planning to work on in the immediate future.

  1. A protocol for view controllers that implements default peek and pop for force touch.
  2. A protocol for view controllers that drops down an error banner.

License

Standard Template Protocols is released under the MIT license. See LICENSE for details.

Comments
  • Tappable is more natural

    Tappable is more natural

    The Tappable protocol closer reflects UIKit's TouchUpInside gesture.

    • A tap down from inside the UIView can be moved out of range, causing the button to not be pressed. If the gesture is moved back in range, the tap is reengaged.
    • The previous implementation did not allow a tap to be cancelled by the user.
    opened by crenwick 1
  • Many issues with Xcode 8, swift 3

    Many issues with Xcode 8, swift 3

    Hello! First thank you very much for this library, that's great work, well done!

    I've some troubles to make it work with Xcode 8. Actually It was not even compilling. So I decided to make some changes on it to fit requirements of swift 3.

    Now it's working fine, I can drag, zoom, rotate etc. But I've got a lot of bugs :

    • When dragging, after releasing my finger, I can't drag anymore everywhere in my superview. It's like the superview were translate as well. But if I print the coordinate of the superview it is still at the right place. Also the center point of the view will always remain the same, even after moving it (the center of the view is relative the its superview).
    • Once the view rotated or zoom in, it's over, the view will mismatch my move and ends somewhere hidden in the window...

    So I'm wondering if I've done something wrong when adapting the library for swift 3, do you experience the same issues?

    Thanks!

    Ok I managed to fix the issue in the Moveable extension by replacing the .began case with this :

    let superCenter = self.convert(self.center, to: self.superview!)
    startPoint = CGPoint(x: superCenter.x - self.superview!.frame.width/2 + self.frame.width/2 , y: superCenter.y - self.superview!.frame.height/2 + self.frame.height/2)
    currentPoint = startPoint
    

    But still when after totaled the view, when I try to drag the view, the translation happens in the referencial of the subview, instead of the superview

    opened by RomeHein 0
  • Many issues with Xcode 8, swift 3

    Many issues with Xcode 8, swift 3

    Hello! First thank you very much for this library, that's great work, well done!

    I've some troubles to make it work with Xcode 8. Actually It was not even compilling. So I decided to make some changes on it to fit requirements of swift 3.

    Now it's working fine, I can drag, zoom, rotate etc. But I've got a lot of bugs :

    • When dragging, after releasing my finger, I can't drag anymore everywhere in my superview. It's like the superview were translate as well. But if I print the coordinate of the superview it is still at the right place.
    • Once the view rotated or zoom in, it's over, the view will mismatch my move and ends somewhere hidden in the window...

    So I'm wondering if I've done something wrong when adapting the library for swift 3, do you experience the same issues?

    Thanks!

    opened by RomeHein 0
  • Correct the spelling of CocoaPods in README

    Correct the spelling of CocoaPods in README

    This pull requests corrects the spelling of CocoaPods 🤓 https://github.com/CocoaPods/shared_resources/tree/master/media

    Created with cocoapods-readme.

    opened by ReadmeCritic 0
  • [readme] Improve cocoapods and contribution suggestions

    [readme] Improve cocoapods and contribution suggestions

    Usually you recommend people don't include a pod version, since 1) you don't have to remember to update the readme with every version and 2) they get the latest updates every time they run pod install. Also mentioning in the contributions section that pull requests are welcome - they are, right? :stuck_out_tongue_winking_eye:

    opened by jbinney 0
  • Carthage Support?

    Carthage Support?

    Seems interesting ~ Would love to pull this using Carthage. Could you add to your target. Trying to avoid the overhead of pods. Carthage simpler and easy to update.

    opened by mingsai 0
Releases(0.3.0)
Owner
Chris
Chris
FluxCapacitor makes implementing Flux design pattern easily with protocols and typealias.

FluxCapacitor makes implementing Flux design pattern easily with protocols and typealias. Storable protocol Actionable protocol Dispatch

Taiki Suzuki 123 Aug 23, 2022
Swift package containing collection protocols.

swift-collection-protocols A package containing collection protocols, for the Swift programming language. Overview No overview available. Availability

Alexandre H. Saad 0 Jul 28, 2022
Simple utility for only executing code every so often.

Rate Limit Simple utility for only executing code every so often. This will only execute the block passed for a given name if the last time it was cal

Sam Soffes 921 Nov 20, 2022
Pavel SurovĂ˝ 0 Jan 1, 2022
RNH Tracker is a GPS logger for iOS (iPhone, iPad, iPod) Track your location and send your logs to RNH Regatta :-)

RNH Tracker for iOS + WatchOS RNH Tracker is a GPS logger for iOS (iPhone, iPad, iPod) with offline map cache support. Track your location, add waypoi

Ed Cafferata 0 Jan 23, 2022
Record your position and export your trip in GPX with GPS Stone on iOS.

GPS Stone Register your trips and export them as GPX files. Notes We currently have included a UIRequiredDeviceCapabilities with a location-services v

Frost Land 11 Sep 24, 2022
Automatically set your keyboard's backlight based on your Mac's ambient light sensor.

QMK Ambient Backlight Automatically set your keyboard's backlight based on your Mac's ambient light sensor. Compatibility macOS Big Sur or later, a Ma

Karl Shea 29 Aug 6, 2022
LibAuthentication will simplify your code when if you want to use FaceID/TouchID in your tweaks.

LibAuthentication will simplify your code when if you want to use FaceID/TouchID in your tweaks.

Maximehip 6 Oct 3, 2022
Generate a privacy policy for your iOS app

PrivacyFlash Pro To easily run PrivacyFlash Pro get the latest packaged release. Learn more about PrivacyFlash Pro in our research paper. PrivacyFlash

privacy-tech-lab 141 Dec 22, 2022
Tweak your iOS app without recompiling!

SwiftTweaks Adjust your iOS app on the fly without waiting to re-compile! Your users won’t see your animation study, Sketch comps, or prototypes. What

Khan Academy 1.4k Dec 28, 2022
Read iOS 15 privacy insight '.ndjson' file into your human brain.

Insight Read iOS 15 privacy insight '.ndjson' file into your human brain. Written in SwiftUI. Feature Compile records into app summary Relink app info

Lakr Aream 151 Nov 11, 2022
Versions tracker for your iOS, macOS, and tvOS app

VersionTrackerSwift VersionTrackerSwift is a versions / builds tracker to know which version has been installed by a user. Usage In your ApplicationDe

Tom Baranes 82 Oct 5, 2022
A way to easily add Cocoapod licenses and App Version to your iOS App using the Settings Bundle

EasyAbout Requirements: cocoapods version 1.4.0 or above. Why you should use Well, it is always nice to give credit to the ones who helped you ?? Bonu

JoĂŁo Mourato 54 Apr 6, 2022
Tweak your iOS app without recompiling!

SwiftTweaks Adjust your iOS app on the fly without waiting to re-compile! Your users won’t see your animation study, Sketch comps, or prototypes. What

Khan Academy 1.4k Dec 28, 2022
Alert popup to notify your users if they use an unsupported iOS version

UnsupportedOSVersionAlert This source code alerts your users if they use your app with an unsupported version of iOS (e.g. iOS 10.0 beta). The alert l

Josef Moser 8 Mar 11, 2019
A cross-platform library of Swift utils to ease your iOS | macOS | watchOS | tvOS and Linux development.

Mechanica A library of Swift utils to ease your iOS, macOS, watchOS, tvOS and Linux development. Requirements Documentation Installation License Contr

Alessandro 28 Aug 28, 2022
A visual developer tool for inspecting your iOS application data structures.

Tree Dump Debugger A visual developer tool for inspecting your iOS application data structures. Features Inspect any data structure with only one line

null 8 Nov 2, 2022
CipherCode - iOS App to decode your secret message

CipherCode IOS App to decode/encode your secret message App App consist of welco

Doston Rustamov 0 Jan 15, 2022
FancyGradient is a UIView subclass which let's you animate gradients in your iOS app. It is purely written in Swift.

FancyGradient is a UIView subclass which let's you animate gradients in your iOS app. It is purely written in Swift. Quickstart Static gradient let fa

Derek Jones 11 Aug 25, 2022