Skip to content

Instantly share code, notes, and snippets.

@mayoralito
Created February 27, 2018 04:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mayoralito/1ca98b193d71c39d0235db3e9157ee21 to your computer and use it in GitHub Desktop.
Save mayoralito/1ca98b193d71c39d0235db3e9157ee21 to your computer and use it in GitHub Desktop.
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