Created
February 27, 2018 04:26
-
-
Save mayoralito/1ca98b193d71c39d0235db3e9157ee21 to your computer and use it in GitHub Desktop.
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 | |
// MARK: - UIColor | |
extension UIColor { | |
static func rbg(r: CGFloat, g: CGFloat, b: CGFloat) -> UIColor { | |
return UIColor(red: r/255, green: g/255, blue: b/288, alpha: 1) | |
} | |
convenience init?(hex: String, alpha: CGFloat = 1.0) { | |
var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines) | |
hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "") | |
var rgb: UInt32 = 0 | |
var r: CGFloat = 0.0 | |
var g: CGFloat = 0.0 | |
var b: CGFloat = 0.0 | |
var a: CGFloat = alpha | |
let length = hexSanitized.count | |
guard Scanner(string: hexSanitized).scanHexInt32(&rgb) else { return nil } | |
if length == 6 { | |
r = CGFloat((rgb & 0xFF0000) >> 16) / 255.0 | |
g = CGFloat((rgb & 0x00FF00) >> 8) / 255.0 | |
b = CGFloat(rgb & 0x0000FF) / 255.0 | |
} else if length == 8 { | |
r = CGFloat((rgb & 0xFF000000) >> 24) / 255.0 | |
g = CGFloat((rgb & 0x00FF0000) >> 16) / 255.0 | |
b = CGFloat((rgb & 0x0000FF00) >> 8) / 255.0 | |
a = CGFloat(rgb & 0x000000FF) / 255.0 | |
} else { | |
return nil | |
} | |
self.init(red: r, green: g, blue: b, alpha: a) | |
} | |
// MARK: - Computed Properties | |
var toHex: String? { | |
return toHex() | |
} | |
// MARK: - From UIColor to String | |
func toHex(alpha: Bool = false) -> String? { | |
guard let components = cgColor.components, components.count >= 3 else { | |
return nil | |
} | |
let r = Float(components[0]) | |
let g = Float(components[1]) | |
let b = Float(components[2]) | |
var a = Float(1.0) | |
if components.count >= 4 { | |
a = Float(components[3]) | |
} | |
if alpha { | |
return String(format: "%02lX%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255), lroundf(a * 255)) | |
} else { | |
return String(format: "%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255)) | |
} | |
} | |
static let backgroundColor = UIColor.rbg(r: 21, g: 22, b: 33) | |
static let outlineStrokeColor = UIColor.rbg(r: 234, g: 45, b: 111) | |
static let trackStrokeColor = UIColor.rbg(r: 56, g: 25, b: 49) | |
static let pulsatingFillColor = UIColor.rbg(r: 86, g: 30, b: 63) | |
// Default definition | |
static var defaultBackgroundColor = UIColor(hex: "112633")! | |
static var defaultTopBackgroundColor = UIColor(hex: "008bf3")! | |
static var defaultTextButtonColor = UIColor(hex: "008BF3")! | |
static var selectedTextButtonColor = UIColor(hex: "008BF3")! | |
static var defaultTextColor = UIColor(hex: "CDD0D2")! | |
static var secondaryTextColor = UIColor(hex: "66757F")! | |
static var hyperLinkTextColor = UIColor(hex: "008BF3")! | |
static var warningColor = UIColor(hex: "f0ad4e") | |
static var okColor = UIColor(hex: "5cb85c") | |
static var errorColor = UIColor(hex: "F50023") | |
static var disabledButtonBackgroundColor = UIColor(hex: "c4c9d1")! | |
} | |
// MARK: - UITabBarController | |
extension UITabBarController { | |
open override var childViewControllerForStatusBarStyle: UIViewController? { | |
return selectedViewController | |
} | |
} | |
// MARK: - UINavigationController | |
extension UINavigationController { | |
open override var childViewControllerForStatusBarStyle: UIViewController? { | |
return visibleViewController | |
} | |
} | |
// MARK: - UIView | |
extension UIView { | |
func safeAreaSetup(for viewController: UIViewController) { | |
let view = viewController.view! | |
let margins = view.layoutMarginsGuide | |
NSLayoutConstraint.activate([ | |
self.leadingAnchor.constraint(equalTo: margins.leadingAnchor), | |
self.trailingAnchor.constraint(equalTo: margins.trailingAnchor) | |
]) | |
if #available(iOS 11, *) { | |
let guide = view.safeAreaLayoutGuide | |
NSLayoutConstraint.activate([ | |
self.topAnchor.constraintEqualToSystemSpacingBelow(guide.topAnchor, multiplier: 1.0), | |
guide.bottomAnchor.constraintEqualToSystemSpacingBelow(self.bottomAnchor, multiplier: 1.0) | |
]) | |
} else { | |
let standardSpacing: CGFloat = 0 | |
NSLayoutConstraint.activate([ | |
self.topAnchor.constraint(equalTo: viewController.topLayoutGuide.bottomAnchor, constant: standardSpacing), | |
viewController.bottomLayoutGuide.topAnchor.constraint(equalTo: self.bottomAnchor, constant: standardSpacing) | |
]) | |
} | |
} | |
var safeTopAnchor: NSLayoutYAxisAnchor { | |
if #available(iOS 11.0, *) { | |
return self.safeAreaLayoutGuide.topAnchor | |
} else { | |
return self.topAnchor | |
} | |
} | |
var safeLeftAnchor: NSLayoutXAxisAnchor { | |
if #available(iOS 11.0, *) { | |
return self.safeAreaLayoutGuide.leftAnchor | |
} else { | |
return self.leftAnchor | |
} | |
} | |
var safeRightAnchor: NSLayoutXAxisAnchor { | |
if #available(iOS 11.0, *) { | |
return self.safeAreaLayoutGuide.rightAnchor | |
} else { | |
return self.rightAnchor | |
} | |
} | |
var safeBottomAnchor: NSLayoutYAxisAnchor { | |
if #available(iOS 11.0, *) { | |
return self.safeAreaLayoutGuide.bottomAnchor | |
} else { | |
return self.bottomAnchor | |
} | |
} | |
} | |
// MARK: - UITextField | |
extension UITextField { | |
var placeholderColor: UIColor? { | |
get { | |
return attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor ?? UIColor.clear | |
} | |
set { | |
guard let color = newValue else { return } | |
let placeholderText = self.placeholder ?? "" | |
attributedPlaceholder = NSAttributedString( | |
string: placeholderText, | |
attributes: [NSAttributedStringKey.foregroundColor: color.withAlphaComponent(self.alpha)] | |
) | |
} | |
} | |
} | |
struct AppFontName { | |
// Palatino | |
// Menlo | |
static let regular = "Menlo-Regular" | |
static let bold = "Menlo-Bold" | |
static let italic = "Menlo-Italic" | |
} | |
// https://stackoverflow.com/questions/8707082/set-a-default-font-for-whole-ios-app | |
// MARK: - Swizzling | |
// Not fully test | |
extension UIFont { | |
@objc class func mySystemFont(ofSize size: CGFloat) -> UIFont { | |
return UIFont(name: AppFontName.regular, size: size)! | |
} | |
@objc class func myBoldSystemFont(ofSize size: CGFloat) -> UIFont { | |
return UIFont(name: AppFontName.bold, size: size)! | |
} | |
@objc class func myItalicSystemFont(ofSize size: CGFloat) -> UIFont { | |
return UIFont(name: AppFontName.italic, size: size)! | |
} | |
@objc convenience init(myCoder aDecoder: NSCoder) { | |
if let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor { | |
if let fontAttribute = fontDescriptor.fontAttributes[.nsctFontUIUsage] as? String { | |
var fontName = "" | |
switch fontAttribute { | |
case "CTFontRegularUsage": | |
fontName = AppFontName.regular | |
case "CTFontEmphasizedUsage", "CTFontBoldUsage": | |
fontName = AppFontName.bold | |
case "CTFontObliqueUsage": | |
fontName = AppFontName.italic | |
default: | |
fontName = AppFontName.regular | |
} | |
let preferredDescriptor = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline) | |
self.init(name: fontName, size: preferredDescriptor.pointSize)! | |
} else { | |
self.init(myCoder: aDecoder) | |
} | |
} else { | |
self.init(myCoder: aDecoder) | |
} | |
} | |
class func overrideInitialize() { | |
if self == UIFont.self { | |
let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:))) | |
let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:))) | |
method_exchangeImplementations(systemFontMethod!, mySystemFontMethod!) | |
let boldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:))) | |
let myBoldSystemFontMethod = class_getClassMethod(self, #selector(myBoldSystemFont(ofSize:))) | |
method_exchangeImplementations(boldSystemFontMethod!, myBoldSystemFontMethod!) | |
let italicSystemFontMethod = class_getClassMethod(self, #selector(italicSystemFont(ofSize:))) | |
let myItalicSystemFontMethod = class_getClassMethod(self, #selector(myItalicSystemFont(ofSize:))) | |
method_exchangeImplementations(italicSystemFontMethod!, myItalicSystemFontMethod!) | |
let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:))) // Trick to get over the lack of UIFont.init(coder:)) | |
let myInitCoderMethod = class_getInstanceMethod(self, #selector(UIFont.init(myCoder:))) | |
method_exchangeImplementations(initCoderMethod!, myInitCoderMethod!) | |
} | |
} | |
func setHeadlineFont() -> UIFont? { | |
// https://grokswift.com/custom-fonts/ | |
// StarJediOutline | |
let preferredDescriptor = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline) | |
return UIFont(name: "Menlo", size: preferredDescriptor.pointSize) | |
} | |
} | |
extension UIFontDescriptor.AttributeName { | |
static let nsctFontUIUsage = UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute") | |
} | |
// MARK: - Custom Extension | |
protocol StructIterable { | |
func properties() throws -> [String: Any] | |
} | |
extension StructIterable { | |
func properties() throws -> [String: Any] { | |
var items: [String: Any] = [:] | |
let mirror = Mirror(reflecting: self) | |
guard let style = mirror.displayStyle, (style == .struct || style == .class) else { | |
throw NSError(domain: "domain.web.appName", code: -007, userInfo: nil) | |
} | |
for (key, value) in mirror.children { | |
guard let varName = key else { | |
continue | |
} | |
items[varName] = value | |
} | |
return items | |
} | |
} | |
extension String { | |
func isAlphanumeric() -> Bool { | |
return !isEmpty && (self.rangeOfCharacter(from: CharacterSet.alphanumerics.inverted) == nil) | |
} | |
func isAlphanumeric(ignoreDiacritics: Bool = false) -> Bool { | |
if ignoreDiacritics { | |
return self.range(of: "[^a-zA-Z0-9]", options: .regularExpression) == nil && self != "" | |
} else { | |
return self.isAlphanumeric() | |
} | |
} | |
func isValidEmail() -> Bool { | |
var isValidString = false | |
do { | |
let regex = try NSRegularExpression(pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", options: .caseInsensitive) | |
isValidString = regex.firstMatch(in: self, options: [], range: NSRange(location: 0, length: self.count)) != nil | |
} catch let error { | |
print("Error ocurred while validating email: \(error.localizedDescription)") | |
} | |
return isValidString | |
} | |
func isValidPassword() -> Bool { | |
return (self.count < 10) ? false : true | |
} | |
} | |
extension UIViewController { | |
func hideKeyboardWhenTappedAround() { | |
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard)) | |
tap.cancelsTouchesInView = false | |
view.addGestureRecognizer(tap) | |
} | |
@objc func dismissKeyboard() { | |
view.endEditing(true) | |
} | |
} | |
extension UILabel { | |
func underline() { | |
let underlineAttribute = [NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue] | |
let underlineAttributedString = NSAttributedString(string: self.text!, attributes: underlineAttribute) | |
self.attributedText = underlineAttributedString | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment