Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/huri000/CrownControl

CrownControl is a tiny accessory that makes scrolling through scrollable content possible without lifting your thumb.
https://github.com/huri000/CrownControl

collection-view crown-view-controller digital-crown ios scroll scrolling scrollview scrollview-component swift table-view user-interaction

Last synced: about 2 months ago
JSON representation

CrownControl is a tiny accessory that makes scrolling through scrollable content possible without lifting your thumb.

Lists

README

        

# CrownControl

[![Platform](http://img.shields.io/badge/platform-iOS-blue.svg?style=flat)](https://developer.apple.com/iphone/index.action)
[![Language](http://img.shields.io/badge/language-Swift-brightgreen.svg?style=flat)](https://developer.apple.com/swift)
[![Version](https://img.shields.io/cocoapods/v/CrownControl.svg?style=flat-square)](http://cocoapods.org/pods/CrownControl)
[![codecov](https://codecov.io/gh/huri000/CrownControl/branch/master/graph/badge.svg)](https://codecov.io/gh/huri000/CrownControl)
[![License](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat)](http://mit-license.org)
![](https://travis-ci.com/huri000/CrownControl.svg?branch=master)

* [Overview](#overview)
* [Features](#features)
* [Example Project](#example-project)
* [Requirements](#requirements)
* [Installation](#installation)
* [Usage](#usage)
* [Quick Usage](#quick-usage)
* [Crown Attributes](#crown-attributes)
* [Scroll Axis](#scroll-axis)
* [Anchor Position](#anchor-position)
* [Spin Direction](#spin-direction)
* [User Interaction](#user-interaction)
* [Style](#style)
* [Sizes](#sizes)
* [Feedback](#feedback)
* [Author](#author)
* [License](#license)

## Overview

Inspired by Apple Watch Digital Crown, CrownControl is a tiny accessory view that makes scrolling through scrollable content possible without lifting your thumb.

### Features

The crown consists of background and foreground surfaces.
The foreground is an indicator which spins around the center as the attached scroll view offset changes.

- [x] Can be repositioned either using force touch or long press.
- [x] Can be spinned clockwise and counter clockwise.
- [x] Most of the user interaction actions are configurable.
- [x] The background and foreground sizes are configurable.
- [x] Can be fully stylized.

## Example Project

The example project contains samples where each demonstrates the CrownControl usability in a scrollable context.

Web View / PDF | Contacts | Photo Collection
--- | --- | ---
![pdf_example](https://github.com/huri000/assets/blob/master/crown-control/pdf.gif) | ![contacts_example](https://github.com/huri000/assets/blob/master/crown-control/contacts.gif) | ![photos_example](https://github.com/huri000/assets/blob/master/crown-control/photos.gif)

## Requirements

- iOS 9 or any higher version.
- Swift 4.2 or any higher version.
- CrownControl leans heavily on [QuickLayout](https://github.com/huri000/QuickLayout) - A lightwight library written in Swift that is used to easily layout views programmatically.

## Installation

### CocoaPods

[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:

```bash
$ gem install cocoapods
```

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

```ruby
source 'https://github.com/cocoapods/specs.git'
platform :ios, '9.0'
use_frameworks!

pod 'CrownControl', '1.0.0'
```

Then, run the following command:

```bash
$ pod install
```

## Usage

### Quick Usage

Using `CrownControl` is really simple.

In your view:

1. Define and bind `CrownAttributes` to a scroll view instance, and optionally customize the attributes.
2. Instantiate and bind the `CrownControl` instance to the `CrownAttributes` instance.
3. Setup the `CrownControl` instance in a given superview using constraints to determine its position.

```Swift

private var crownControl: CrownControl!
private var scrollView: UIScrollView!

private func setupCrownViewController() {
let attributes = CrownAttributes(scrollView: scrollView, scrollAxis: .vertical)

// Cling the bottom of the crown to the bottom of a view with -50 offset
let verticalConstraint = CrownAttributes.AxisConstraint(crownEdge: .bottom, anchorView: scrollView, anchorViewEdge: .bottom, offset: -50)

// Cling the trailing edge of the crown to the trailing edge of a view with -50 offset
let horizontalConstraint = CrownAttributes.AxisConstraint(crownEdge: .trailing, anchorView: scrollView, anchorViewEdge: .trailing, offset: -50)

// Setup the crown control within *self*
crownControl = CrownControl(attributes: attributes, delegate: self)
crownControl.layout(in: view, horizontalConstaint: horizontalConstraint, verticalConstraint: verticalConstraint)
}
```

To make the crown respond to scrolling events that emanates from any other invoker but the crown, add to `scrollViewDidScroll(_:)` the following:

```Swift
func scrollViewDidScroll(_ scrollView: UIScrollView) {
crownControl?.spinToMatchScrollViewOffset()
}
```

### Crown Attributes

`CrownAttributes` is the crown appearance descriptor.
Its nested properties describe the look and feel of the crown.

#### Scroll Axis

The axis of the scroll view is a `.horizontal` or `.vertical`. It must be set during `CrownAttributes` initialization.

#### Anchor Position

The anchor position of the foreground indicator. Indicates where the foreground is initially positioned.

```Swift
attributes.anchorPosition = .left
```

The posssible values are `.left`, `.right`, `.top`, `.bottom`.
The default value is `.top`.

#### Spin Direction

The direction to which the the indicator spins.

Example for setting the spin direction to be counter-clockwise.
```Swift
attributes.spinDirection = .counterClockwise
```

The default value is `clockwise`.

#### User Interaction

Describes the user interaction with the crown.
Currently supported user interaction gestures: tap, double tap, long-press, and force-touch events.

##### Tap Gestures

When a single tap event occurs, scroll forward with the specified offset value:
```Swift
attributes.userInteraction.singleTap = .scrollsForwardWithOffset(value: 20, animated: true)
```

When a single tap event occurs, perform a custom action.
```Swift
attributes.userInteraction.singleTap = .custom(action: {
/* Do something */
})
```

When a double tap event occurs, scroll to the leading edge of the scroll view.
```Swift
attributes.userInteraction.doubleTap = .scrollsToLeadingEdge
```

##### Drag and Drop

The crown can be dragged and dropped using force-touch if the force-touch trait is supported by the device hardware. If not, there is a fallback to long-press gesture.
```Swift
attributes.repositionGesture = .prefersForceTouch(attributes: .init())
```

#### Style

The background and foreground surfaces can be customized with various styles.

Example for setting the crown background to a gradient style, and its border to a specific color and width.
```Swift
attributes.backgroundStyle.content = .gradient(gradient: .init(colors: [.white, .gray], startPoint: .zero, endPoint: CGPoint(x: 1, y: 1)))
attributes.backgroundStyle.border = .value(color: .gray, width: 1)
```

#### Sizes

Describes the size of the crown and relations between the foreground and the background surfaces.

In the following example, setting `scrollRelation` property to 10 means that 10 full spins of the foreground would make the scroll view offset reach its trailing edge.
```Swift
attributes.sizes.scrollRelation = 10
```

Example for setting the edge size (width and height) of the crown to 60pts, and the foreground edge ratio to 25 precent of that size, which is 15pts.
```Swift
attributes.sizes.backgroundSurfaceDiameter = 60
attributes.sizes.foregroundSurfaceEdgeRatio = 0.25
```

#### Feedback

Feedback descriptor for the foreground when it reaches the anchor point on the crown surface.

The device generates impact-haptic-feedback when the scroll-view offset reaches the leading edge.
The background surface of the crown flashes with color.
```Swift
attributes.feedback.leading.impactHaptic = .light
attributes.feedback.leading.backgroundFlash = .active(color: .white, fadeDuration: 0.3)
```

## Author

Daniel Huri, [email protected]

## License

CrownControl is available under the MIT license. See the [LICENSE](/LICENSE) file for more info.