This file contains 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
extension UIImage { | |
static func fromInitials(_ string: String, size: CGSize, backGroundColor: UIColor, textAttributes: [NSAttributedString.Key: Any]? = nil) -> UIImage? { | |
let text = string.initials | |
let scale = Float(UIScreen.main.scale) | |
UIGraphicsBeginImageContextWithOptions(size, false, CGFloat(scale)) | |
let context = UIGraphicsGetCurrentContext() | |
context?.setFillColor(backGroundColor.cgColor) | |
context?.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height)) |
This file contains 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
func memoize<T: Hashable, U>(work: @escaping (T)->U) -> (T)->U { | |
var memo = Dictionary<T, U>() | |
return { x in | |
if let q = memo[x] { return q } | |
let r = work(x) | |
memo[x] = r | |
return r | |
} | |
} |
This file contains 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
extension Encodable { | |
var asDictionary: [String: Any]? { | |
guard let data = try? JSONEncoder().encode(self) else { return nil } | |
return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)).flatMap { $0 as? [String: Any] } | |
} | |
} | |
extension Decodable { | |
static func fromDictionary(from json: Any) -> Self? { | |
guard let jsonData = try? JSONSerialization.data(withJSONObject: json, options: []) else { |
This file contains 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
extension UIView { | |
func allSubviews<T: UIView>(of type: T.Type) -> [T] { | |
let directSubviews = subviews.compactMap({ $0 as? T }) | |
var nested = [T]() | |
for s in subviews { | |
let ss = s.allSubviews(of: type) | |
nested += ss | |
} |
This file contains 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
struct Cached <V, C> { | |
typealias Computation = (V) -> C | |
private var computation: (V) -> C | |
private var cachedResult: C? | |
var value: V { | |
willSet { | |
cachedResult = nil | |
} | |
} |
This file contains 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
extension UIView { | |
func makeCircular() -> NSKeyValueObservation { | |
self.layer.cornerRadius = self.bounds.width/2 | |
clipsToBounds = true | |
let observation = observe(\UIView.bounds, changeHandler: { this, change in | |
this.layer.cornerRadius = this.bounds.width/2 | |
}) | |
return observation | |
} |
This file contains 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
@IBDesignable | |
class RevealView: UIView { | |
var contentHeight: CGFloat = 300 | |
@IBInspectable var title: String = "" { | |
didSet { | |
titleLabel.text = title | |
} | |
} |
This file contains 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
extension UIScrollView { | |
func scrollSubViewToTop(_ subview: UIView, offset: CGFloat, animated: Bool) { | |
let point = convert(subview.frame.origin, from: subview.superview ?? subview) | |
setContentOffset(CGPoint(x: 0, y: point.y - offset), animated: animated) | |
} | |
func viewPortOffset(of subview: UIView) -> CGFloat { | |
let point = convert(subview.frame.origin, from: subview.superview ?? subview) | |
return point.y - contentOffset.y | |
} |
This file contains 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
/* | |
It is encouraged to use the same class name for the controller story board identifier, | |
but this protocol is flexible to allow defining the story from where to instantiate the | |
controller as well its identifier. | |
You can choose to keep the convention while just changing the story board where the controller | |
is located. | |
e.g: | |
This file contains 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
import UIKit | |
import Foundation | |
protocol Coordinator: class { | |
typealias ExitHandler = (Coordinator) -> Void | |
var childCoordinators: [Coordinator] { get set } | |
var navigationController: UINavigationController { get set } | |
var initialViewController: UIViewController? { get } | |
func willNavigate(from: UIViewController, to: UIViewController) | |
func start() |