あたも技術ブログ

セットジャパンコーポレーションの社員が運営しています。

【Swift】よく使うextension集

extensionとは

既存のクラスに対し、メソッド、プロパティを追加することができる機能です。

Obj-Cで言うところのカテゴリと同じような機能で, 既存クラスで同じような処理を何箇所も行う場合は、extensionでまとめてしまうことで可読性や保守性が向上するかと思います。

UIApplication

extension UIApplication {

    /// 表示中のViewControllerを取得する
    ///
    /// - returns: UIViewController
    func currentViewController() -> UIViewController {
        var current: UIViewController
        var root = (self.windows.first?.rootViewController)! as UIViewController
        
        // モーダルビューが存在した場合はトップのものを取得
        while root.presentedViewController != nil {
            root = root.presentedViewController!
        }
        
        // rootがナビゲーションコントローラならば最後のViewControllerを取得
        if root.isKind(of: UINavigationController.classForCoder()) {
            current = (root as! UINavigationController).viewControllers.last!
        }
            // rootがタブバーコントローラならば選択中のViewControllerを取得
        else if root.isKind(of: UITabBarController.classForCoder()) {
            let selected = (root as! UITabBarController).selectedViewController
            
            // 選択中がナビゲーションコントローラならば最後のViewControllerを取得
            if (selected?.isKind(of: UINavigationController.classForCoder()))! {
                current = (selected as! UINavigationController).viewControllers.last!
            }
            else {
                current = selected!
            }
        }
        else {
            current = root
        }
        return current
    }
}

// 使い方
let current = UIApplication.shared.currentViewController()

UIView

extension UIView {
    /// subViewを全削除
    func removeAllSubViews() {
        self.subviews.forEach{
            $0.removeFromSuperview()
        }
    }
    
    /// キャプチャを取得
    ///
    /// - Returns: イメージ
    func capture() -> UIImage {
        
        // キャプチャする範囲を取得.
        let rect = self.bounds
        
        // ビットマップ画像のcontextを作成.
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
        let context: CGContext = UIGraphicsGetCurrentContext()!
        
        // 対象のview内の描画をcontextに複写する.
        self.layer.render(in: context)
        
        // 現在のcontextのビットマップをUIImageとして取得.
        let capturedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        
        // contextを閉じる.
        UIGraphicsEndImageContext()
        
        return capturedImage
    }
}

// 使い方
self.view.removeAllSubViews()
let captureImage = self.view.capture()

UIImage

extension UIImage {
    
    /// 色とサイズを指定してイメージを生成します
    ///
    /// - parameter color: 色
    /// - parameter size:  サイズ
    ///
    /// - returns: イメージ
    class func generate(color: UIColor, _ size: CGSize = CGSize(width: 100, height: 100)) -> UIImage {
        let rect: CGRect = CGRect(origin: CGPoint.zero, size: size)
        
        UIGraphicsBeginImageContext(rect.size)
        let context: CGContext = UIGraphicsGetCurrentContext()!
        
        context.setFillColor(color.cgColor)
        context.fill(rect)
        
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}

// 使い方
UIImage.generate(color: .red, CGSize(width: 150, height: 150))

String

extension String {
    /// MD5ハッシュ値を取得
    var md5: String! {
        let str = self.cString(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
        let strLen = CC_LONG(self.lengthOfBytes(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue)))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
        
        CC_MD5(str!, strLen, result)
        
        let hash = NSMutableString()
        for i in 0..<digestLen {
            hash.appendFormat("%02x", result[i])
        }
        
        result.deallocate(capacity: digestLen)
        
        return String(format: hash as String)
    }
}

// 使い方
let md5Hash = "ABCDEFG".md5

UIFont

extension UIFont {
    class var hiragino: UIFont{
        return UIFont(name: "HiraKakuProN-W3", size: UIFont.preferredFont(forTextStyle: .body).pointSize)!
    }
    
    class var hiraginoBold: UIFont{
        return UIFont(name: "HiraKakuProN-W6", size: UIFont.preferredFont(forTextStyle: .body).pointSize)!
    }
    
    class var hiraginoMincho: UIFont{
        return UIFont(name: "Hiragino Mincho ProN W3", size: UIFont.preferredFont(forTextStyle: .body).pointSize)!
    }
    
    class var hiraginoMinchoBold: UIFont{
        return UIFont(name: "Hiragino Mincho ProN W6", size: UIFont.preferredFont(forTextStyle: .body).pointSize)!
    }
}

// 使い方
let hiraginoFont = UIFont.hiragino
let hiraginoBoldFont = UIFont.hiraginoBold
let hiraginoMinchoFont = UIFont.hiraginoMincho
let hiraginoMinchoBoldFont = UIFont. hiraginoMinchoBold

上記の他にも使っているものはたくさんあるのですが、自分で書いたものではなく、出典のわからないものなど多いので、以上になります。

自分用のextensionをまとめてライブラリ化し、新規プロジェクト作成時に追加するようにしておけば開発効率がどんどん上がっていくので、暇な時にオープンソースのものを探すのもよいかと思います。