Skip to content

Instantly share code, notes, and snippets.

@Erkened
Last active September 27, 2017 09:18
Show Gist options
  • Save Erkened/2f1a62550988046479482c5e525c5899 to your computer and use it in GitHub Desktop.
Save Erkened/2f1a62550988046479482c5e525c5899 to your computer and use it in GitHub Desktop.
Extensions I use often in my projects. Swift 4.0
import Foundation
import UIKit
extension UIColor{
class var random: UIColor {
let hue : CGFloat = CGFloat(arc4random() % 256) / 256 // use 256 to get full range from 0.0 to 1.0
let saturation : CGFloat = CGFloat(arc4random() % 128) / 256 + 0.5 // from 0.5 to 1.0 to stay away from white
let brightness : CGFloat = CGFloat(arc4random() % 128) / 256 + 0.5 // from 0.5 to 1.0 to stay away from black
return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1)
}
class func hex(_ hex:String, alpha:CGFloat = 1.0) -> UIColor {
var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
if (cString.hasPrefix("#")) {
let index = cString.index(cString.startIndex, offsetBy: 1)
cString = String(cString[index...])
}
if (cString.characters.count != 6) {
return UIColor.gray
}
var rgbValue:UInt32 = 0
Scanner(string: cString).scanHexInt32(&rgbValue)
return UIColor(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: CGFloat(alpha)
)
}
var invert: UIColor {
var red : CGFloat = 255.0
var green : CGFloat = 255.0
var blue : CGFloat = 255.0
var alpha : CGFloat = 1.0
self.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
red = 255.0 - (red * 255.0)
green = 255.0 - (green * 255.0)
blue = 255.0 - (blue * 255.0)
return UIColor(red: red / 255.0, green: green / 255.0, blue: blue / 255.0, alpha: alpha)
}
}
extension UIFont{
// FONTELLO
public class func fontello(withSize fontSize: CGFloat) -> UIFont{ return self.init(name: "fontello", size: fontSize)! }
}
extension UITextField{
func addDoneButtonToKeyboard(withAction action: Selector?){
let doneToolbar: UIToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: 300, height: 40))
doneToolbar.barStyle = UIBarStyle.default
let flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: action)
var items = [UIBarButtonItem]()
items.append(flexSpace)
items.append(done)
doneToolbar.items = items
doneToolbar.sizeToFit()
self.inputAccessoryView = doneToolbar
}
}
extension String{
var underlined: NSAttributedString {
get {
let textRange = NSMakeRange(0, self.characters.count)
let attributedText = NSMutableAttributedString(string: self)
attributedText.addAttribute(NSUnderlineStyleAttributeName , value: NSUnderlineStyle.styleSingle.rawValue, range: textRange)
return attributedText
}
}
func underlined(withColour colour: UIColor) -> NSAttributedString{
let textRange = NSMakeRange(0, self.characters.count)
let attributedText = NSMutableAttributedString(string: self)
attributedText.addAttribute(NSUnderlineStyleAttributeName , value: NSUnderlineStyle.styleSingle.rawValue, range: textRange)
attributedText.addAttribute(NSForegroundColorAttributeName, value: colour, range: textRange)
return attributedText
}
var localised: String { return NSLocalizedString(self, comment: "") }
}
// Get the topmost view controller
extension UIApplication {
class func topViewController(_ base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(nav.visibleViewController)
}
if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
return topViewController(selected)
}
if let presented = base?.presentedViewController {
return topViewController(presented)
}
return base
}
}
extension NSLayoutConstraint {
public class func useAndActivate(_ constraints: [NSLayoutConstraint]) {
for constraint in constraints {
if let view = constraint.firstItem as? UIView {
view.translatesAutoresizingMaskIntoConstraints = false
}
}
activate(constraints)
}
}
// Make cell identifiers reusable for collection views
// Source: https://medium.com/@gonzalezreal/ios-cell-registration-reusing-with-swift-protocol-extensions-and-generics-c5ac4fb5b75e#.3ey5f2nvs
protocol ReusableView: class {}
extension ReusableView where Self: UIView {
static var reuseIdentifier: String {
return String(describing: self)
}
}
//extension UICollectionViewCell: ReusableView {}
extension UICollectionReusableView: ReusableView {}
extension UICollectionView {
func register<T: UICollectionViewCell>(_: T.Type){
register(T.self, forCellWithReuseIdentifier: T.reuseIdentifier)
}
func dequeueReusableCell<T: UICollectionViewCell>(forIndexPath indexPath: IndexPath) -> T{
guard let cell = dequeueReusableCell(withReuseIdentifier: T.reuseIdentifier, for: indexPath) as? T else{
fatalError("Could not dequeue cell with identifier: \(T.reuseIdentifier)")
}
return cell
}
func registerHeader<T: UICollectionReusableView>(_: T.Type){
register(T.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: T.reuseIdentifier)
}
func registerFooter<T: UICollectionReusableView>(_: T.Type){
register(T.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: T.reuseIdentifier)
}
func dequeueReusableHeader<T: UICollectionReusableView>(forIndexPath indexPath: IndexPath) -> T{
guard let reusableView = dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: T.reuseIdentifier, for: indexPath) as? T else {
fatalError("Could not dequeue header with identifier: \(T.reuseIdentifier)")
}
return reusableView
}
func dequeueReusableFooter<T: UICollectionReusableView>(forIndexPath indexPath: IndexPath) -> T{
guard let reusableView = dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionFooter, withReuseIdentifier: T.reuseIdentifier, for: indexPath) as? T else {
fatalError("Could not dequeue footer with identifier: \(T.reuseIdentifier)")
}
return reusableView
}
}
// This function makes sure the index is in the array by using the "safe" keyword
// Example: if let item = array[safe: index] { .. }
// Source: http://stackoverflow.com/questions/25329186/safe-bounds-checked-array-lookup-in-swift-through-optional-bindings
extension Collection {
/// Returns the element at the specified index iff it is within bounds, otherwise nil.
subscript (safe index: Index) -> Iterator.Element? {
return index >= startIndex && index < endIndex ? self[index] : nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment