Last active
March 24, 2018 14:03
-
-
Save vahan3x/7de13fadd2e03a254e87fa5055d3279c to your computer and use it in GitHub Desktop.
Useful extensions for Cocoa Touch frameworks
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
// Swift version: 4.0 | |
public extension Comparable { | |
/// Returns a copy of the value clamped to the given limiting range. | |
/// | |
/// Example: | |
/// | |
/// let a = 50 | |
/// print(a.clamped(to: 0 ... 10)) // prints 10 | |
/// | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - Parameter limits: The range to clamp the value. | |
/// - Returns: A new value clamped to the bounds of `limits`. | |
public func clamped(to limits: ClosedRange<Self>) -> Self { | |
return min(max(self, limits.lowerBound), limits.upperBound) | |
} | |
/// Clamps the value to the given limiting range. | |
/// | |
/// Example: | |
/// | |
/// var a = -50 | |
/// a.clamp(to: 0 ... 10) | |
/// print(a) // prints 0 | |
/// | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - Parameter limits: The range to clamp the value. | |
public mutating func clamp(to limits: ClosedRange<Self>) { | |
self = clamped(to: limits) | |
} | |
} |
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
// Swift version: 4.0 | |
public extension UIColor { | |
/// Tells if the color will appear light for the human eye. | |
/// - Attention: The alpha component of the color is being ignored. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
public var isLightColor: Bool { | |
var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0 | |
getRed(&red, green: &green, blue: &blue, alpha: nil) | |
return (red * 299.0 + green * 587.0 + blue * 114.0) / 1000.0 >= 0.5; | |
} | |
/// Initializes and returns a color object from the specified hex code. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - Parameter hexCode: Hex code of the color object. | |
public convenience init(hexCode: Int) { | |
self.init(red: CGFloat(0xFF & (hexCode >> 24)) / 255.0, | |
green: CGFloat(0xFF & (hexCode >> 16)) / 255.0, | |
blue: CGFloat(0xFF & (hexCode >> 8)) / 255.0, | |
alpha: CGFloat(0xFF & (hexCode >> 0)) / 255.0) | |
} | |
} | |
/// Multiplies every channel of the color with the multiplier. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - Parameters: | |
/// - color: A color multiplier. | |
/// - multiplier: A number multiplier. | |
/// - Returns: A new color with multiplied channels. | |
public func *(color: UIColor, multiplier: Int) -> UIColor { | |
return color * CGFloat(multiplier) | |
} | |
/// Multiplies every channel of the color with the multiplier. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - Parameters: | |
/// - color: A color multiplier. | |
/// - multiplier: A number multiplier. | |
/// - Returns: A new color with multiplied channels. | |
public func *(color: UIColor, multiplier: Double) -> UIColor { | |
return color * CGFloat(multiplier) | |
} | |
/// Multiplies every channel of the color with the multiplier. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - Parameters: | |
/// - color: A color multiplier. | |
/// - multiplier: A number multiplier. | |
/// - Returns: A new color with multiplied channels. | |
public func *(color: UIColor, multiplier: CGFloat) -> UIColor { | |
var (r, g, b, a) = (CGFloat(0.0), CGFloat(0.0), CGFloat(0.0), CGFloat(0.0)) | |
color.getRed(&r, green: &g, blue: &b, alpha: &a) | |
return UIColor(red: (r * multiplier).clamped(to: 0.0 ... 1.0), | |
green: (g * multiplier).clamped(to: 0.0 ... 1.0), | |
blue: (b * multiplier).clamped(to: 0.0 ... 1.0), | |
alpha: (a * multiplier).clamped(to: 0.0 ... 1.0)) | |
} | |
/// Divides every channel of the color by the divisor. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - Parameters: | |
/// - color: A color dividend. | |
/// - divisor: A number divisor. | |
/// - Returns: A new color with divided channels. | |
public func /(color: UIColor, divisor: Int) -> UIColor { | |
return color / CGFloat(divisor) | |
} | |
/// Divides every channel of the color by the divisor. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - Parameters: | |
/// - color: A color dividend. | |
/// - divisor: A number divisor. | |
/// - Returns: A new color with divided channels. | |
public func /(color: UIColor, divisor: Double) -> UIColor { | |
return color / CGFloat(divisor) | |
} | |
/// Divides every channel of the color by the divisor. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - Parameters: | |
/// - color: A color dividend. | |
/// - divisor: A number divisor. | |
/// - Returns: A new color with divided channels. | |
public func /(color: UIColor, divisor: CGFloat) -> UIColor { | |
var (r, g, b, a) = (CGFloat(0.0), CGFloat(0.0), CGFloat(0.0), CGFloat(0.0)) | |
color.getRed(&r, green: &g, blue: &b, alpha: &a) | |
return UIColor(red: (r / divisor).clamped(to: 0.0 ... 1.0), | |
green: (g / divisor).clamped(to: 0.0 ... 1.0), | |
blue: (b / divisor).clamped(to: 0.0 ... 1.0), | |
alpha: (a / divisor).clamped(to: 0.0 ... 1.0)) | |
} | |
/// Adds values of the two color channels. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - Parameters: | |
/// - lhs: A color addend. | |
/// - rhs: A color addend. | |
/// - Returns: A new color with added channels. | |
public func +(lhs: UIColor, rhs: UIColor) -> UIColor { | |
var (r1, g1, b1, a1) = (CGFloat(0.0), CGFloat(0.0), CGFloat(0.0), CGFloat(0.0)) | |
var (r2, g2, b2, a2) = (CGFloat(0.0), CGFloat(0.0), CGFloat(0.0), CGFloat(0.0)) | |
lhs.getRed(&r1, green: &g1, blue: &b1, alpha: &a1) | |
rhs.getRed(&r2, green: &g2, blue: &b2, alpha: &a2) | |
return UIColor(red: min(r1 + r2, 1.0), | |
green: min(g1 + g2, 1.0), | |
blue: min(b1 + b2, 1.0), | |
alpha: min(a1 + a2, 1.0)) | |
} |
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
// Swift version: 4.0 | |
public extension UIDevice { | |
/// Values identifying the model of a `UIDevice`. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - unknown: Unknown device | |
/// - simulator: A Simulator | |
/// - iPhone1G: iPhone 1st Generation | |
/// - iPhone3G: iPhone 3G | |
/// - iPhone3GS: iPhone 3GS | |
/// - iPhone4: iPhone 4 | |
/// - iPhone4S: iPhone 4S | |
/// - iPhone5: iPhone 5 | |
/// - iPhone5C: iPhone 5C | |
/// - iPhone5S: iPhone 5S | |
/// - iPhone6: iPhone 6 | |
/// - iPhone6Plus: iPhone 6 Plus | |
/// - iPhoneSE: iPhone SE | |
/// - iPhone6S: iPhone 6S | |
/// - iPhone6SPlus: iPhone 6S Plus | |
/// - iPhone7: iPhone 7 | |
/// - iPhone7Plus: iPhone 7 Plus | |
/// - iPhone8: iPhone 8 | |
/// - iPhone8Plus: iPhone 8 Plus | |
/// - iPhoneX: iPhone X | |
public enum Model { | |
case unknown | |
case simulator | |
case iPhone1G | |
case iPhone3G | |
case iPhone3GS | |
case iPhone4 | |
case iPhone4S | |
case iPhone5 | |
case iPhone5C | |
case iPhone5S | |
case iPhone6 | |
case iPhone6Plus | |
case iPhoneSE | |
case iPhone6S | |
case iPhone6SPlus | |
case iPhone7 | |
case iPhone7Plus | |
case iPhone8 | |
case iPhone8Plus | |
case iPhoneX | |
} | |
/// The model of the device. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
public var deviceModel: Model { | |
switch machineName() { | |
case "iPhone1,1": return .iPhone1G | |
case "iPhone1,2": return .iPhone3G | |
case "iPhone2,1": return .iPhone3GS | |
case "iPhone3,1", "iPhone3,3": return .iPhone4 | |
case "iPhone4,1": return .iPhone4S | |
case "iPhone5,1", "iPhone5,2": return .iPhone5 | |
case "iPhone5,3", "iPhone5,4": return .iPhone5C | |
case "iPhone6,1", "iPhone6,2": return .iPhone5S | |
case "iPhone7,2": return .iPhone6 | |
case "iPhone7,1": return .iPhone6Plus | |
case "iPhone8,4": return .iPhoneSE | |
case "iPhone8,1": return .iPhone6S | |
case "iPhone8,2": return .iPhone6SPlus | |
case "iPhone9,1", "iPhone9,3": return .iPhone7 | |
case "iPhone9,2", "iPhone9,4": return .iPhone7Plus | |
case "iPhone10,1", "iPhone10,4": return .iPhone8 | |
case "iPhone10,2", "iPhone10,5": return .iPhone8Plus | |
case "iPhone10,3", "iPhone10,6": return .iPhoneX | |
case "x86_64", "i386": return .simulator | |
default: return .unknown | |
} | |
} | |
/// Gets the current machine's name. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// | |
/// - Returns: Current machine's name. | |
private func machineName() -> String { | |
var systemInfo = utsname() | |
uname(&systemInfo) | |
return String(cString: &systemInfo.machine.0) | |
} | |
} |
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
// Swift version: 4.0 | |
public extension UIScreen { | |
/// A Boolean value indicating whether there is a notch on the screen. | |
/// - Author: [Vahan Babayan](https://github.com/vahan3x) | |
/// - ToDo: Behaviour on the multi-screen devices is undefined, need to figure out a way to detect the notch for the specified screen. | |
public var hasNotch: Bool { | |
if #available(iOS 11.0, *), let insets = UIApplication.shared.keyWindow?.safeAreaInsets { | |
switch UIDevice.current.orientation { | |
case .portrait: return insets.top > 0.0 | |
case .portraitUpsideDown: return insets.bottom > 0.0 | |
case .landscapeLeft: return insets.left > 0.0 | |
case .landscapeRight: return insets.right > 0.0 | |
default: return insets.top > 0.0 || insets.bottom > 0.0 || insets.left > 0.0 || insets.right > 0.0 // Best guess | |
} | |
} | |
return false | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment