Instantly share code, notes, and snippets.
Last active
September 6, 2017 06:05
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save msepcot/a770e5b3fb8040bd7655d76d256d0057 to your computer and use it in GitHub Desktop.
Implement Mail.app's filter button in code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// FadeableButton.swift | |
// Octomino | |
// | |
// Created by Michael Sepcot on 9/5/17. | |
// Copyright © 2017 Head Down Development. All rights reserved. | |
// | |
import UIKit | |
class FadeableButton: UIControl { | |
static private let fadeAlpha:CGFloat = 0.2 | |
static private let fadeDuration = 0.3 | |
static private let touchAccessibilityDrift:CGFloat = 70 | |
private var isFaded = false | |
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { | |
fade(true, animated: false) | |
return true | |
} | |
override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { | |
let expandedTouchTarget = CGRect( | |
x: -FadeableButton.touchAccessibilityDrift, | |
y: -FadeableButton.touchAccessibilityDrift, | |
width: frame.width + FadeableButton.touchAccessibilityDrift * 2, | |
height: frame.height + FadeableButton.touchAccessibilityDrift * 2 | |
) | |
if expandedTouchTarget.contains(touch.location(in: self)) { | |
fade(true, animated: true) | |
} else { | |
fade(false, animated: true) | |
} | |
return true | |
} | |
override func endTracking(_ touch: UITouch?, with event: UIEvent?) { | |
fade(false, animated: true) | |
super.endTracking(touch, with: event) | |
} | |
override func cancelTracking(with event: UIEvent?) { | |
fade(false, animated: true) | |
super.cancelTracking(with: event) | |
} | |
private func fade(_ shouldFade: Bool, animated: Bool) { | |
guard isFaded != shouldFade else { return } | |
isFaded = shouldFade | |
UIView.animate(withDuration: animated ? FadeableButton.fadeDuration : 0.0) { | |
self.alpha = shouldFade ? FadeableButton.fadeAlpha : 1.0 | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// FilterButton.swift | |
// Octomino | |
// | |
// Created by Michael Sepcot on 8/29/17. | |
// Copyright © 2017 Head Down Development. All rights reserved. | |
// | |
import UIKit | |
@IBDesignable class FilterButton: FadeableButton { | |
private let buttonSize:CGFloat = 21 | |
private let topLineLength:CGFloat = 14 | |
private let middleLineLength:CGFloat = 10 | |
private let bottomLineLength:CGFloat = 6 | |
@IBInspectable var _isSelected: Bool = false { | |
willSet { | |
isSelected = newValue | |
} | |
} | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
} | |
required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
} | |
override func draw(_ rect: CGRect) { | |
tintColor.setStroke() | |
tintColor.setFill() | |
let offsetX = (rect.size.width - buttonSize) / 2 | |
let offsetY = (rect.size.height - buttonSize) / 2 | |
let circle = UIBezierPath(ovalIn: CGRect(x: offsetX, y: offsetY, width: buttonSize, height: buttonSize)) | |
if isSelected { | |
circle.fill() | |
} | |
circle.lineWidth = 1 | |
circle.stroke() | |
if isSelected { | |
UIColor.white.setStroke() | |
} | |
let topOffsetX = (rect.size.width - topLineLength) / 2 | |
drawLine(from: CGPoint(x: topOffsetX, y: offsetY + 7), | |
to: CGPoint(x: topOffsetX + topLineLength, y: offsetY + 7)) | |
let middleOffsetX = (rect.size.width - middleLineLength) / 2 | |
drawLine(from: CGPoint(x: middleOffsetX, y: offsetY + 11), | |
to: CGPoint(x: middleOffsetX + middleLineLength, y: offsetY + 11)) | |
let bottomOffsetX = (rect.size.width - bottomLineLength) / 2 | |
drawLine(from: CGPoint(x: bottomOffsetX, y: offsetY + 15), | |
to: CGPoint(x: bottomOffsetX + bottomLineLength, y: offsetY + 15)) | |
} | |
func drawLine(from startPoint: CGPoint, to endPoint: CGPoint) { | |
let line = UIBezierPath() | |
line.move(to: startPoint) | |
line.addLine(to: endPoint) | |
line.lineWidth = 1 | |
line.stroke() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment