Swift Reusable Code Segment

可復用的swift代碼段怎披。為什么用英文做標題盛龄?為了突出“復用”

文章的目的:記錄經(jīng)常使用的代碼塊方便復用
更新次數(shù):將會不定期持續(xù)更新
內(nèi)容來源:有些是從優(yōu)秀開源代碼中摘要的,有些是自己寫的。在此不多做說明。
文章權(quán)限:歡迎收藏轉(zhuǎn)載隘擎,但請勿用于商業(yè)用途

一定程度上說,編寫代碼是一件重復性很高的工作凉夯。當然我并不是說寫出優(yōu)質(zhì)的代碼是一件容易的事情货葬,相反我想表達的是我們在大多數(shù)情況下會重復以前開發(fā)過的內(nèi)容。所以代碼的復用就顯得尤為重要劲够。說到這里我不得不分享一下震桶,最近看到的一篇關于面向?qū)ο笤O計原則的文章。雖然是以Android為描述語言再沧,但思路是相通的不耽誤學習尼夺。

面向?qū)ο蟮?個基本原則:

  • 1尊残、單一職責原則:一個類中應該是一組相關性很高的函數(shù)炒瘸、數(shù)據(jù)的封裝。
  • 2寝衫、開閉原則:簡單的說就是顷扩,一個類只對擴展開放,對修改關閉慰毅。
  • 3隘截、里氏替換原則:所有引用基類的地方必須能透明地使用其子類的對象,簡單的說就是父類能夠使用的地方子類一定能夠使用汹胃。
  • 4婶芭、接口隔離原則:客戶端不應該依賴它不需要的接口∽偶ⅲ可以理解為一個方法中應該避免過多的接口依賴犀农。
  • 5、依賴倒置原則:模塊間的依賴通過抽象發(fā)生宰掉,實現(xiàn)類之間不發(fā)生直接的依賴關系呵哨,其依賴關系是通過接口或抽象類產(chǎn)生的。既面向接口編程轨奄,或者面向抽象類編程挨务。
  • 6谎柄、迪米特原則:也叫最少知識原則果漾。意思是,一個對象應該對其他對象有最少的了解绒障。可以理解為捍歪,一連串的相關處理事件應該抽離封裝出來户辱。對于調(diào)用這個封裝函數(shù)的調(diào)用者变逃,封裝代碼內(nèi)部邏輯是透明的凰棉。 以上六點是java面向?qū)ο蟮脑瓌t福压。其他語言應該也是適用的。
    如果感興趣可以查看原文:面向?qū)ο蟮牧鶄€基本原則

好了偏題結(jié)束。正式"Resualbe"部分铆惑。

基本數(shù)據(jù)類型擴展

1受裹、String 擴展

extension String {

    ///用于計算字符串在高度。
    ///例如晰韵,當需要動態(tài)計算TableVIewCell高度的時候滑蚯,需要根據(jù)某個Label的內(nèi)容String的長度來調(diào)整cell的高度隘膘,讓其能夠全部顯示內(nèi)容纵势。
    func stringHeightWith(fontSize:CGFloat,width:CGFloat)->CGFloat

    {
        let font = UIFont.systemFontOfSize(fontSize)
        let size = CGSizeMake(width,CGFloat.max)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineBreakMode = .ByWordWrapping;
        let  attributes = [NSFontAttributeName:font,
            NSParagraphStyleAttributeName:paragraphStyle.copy()]
        
        let text = self as NSString
        let rect = text.boundingRectWithSize(size, options:.UsesLineFragmentOrigin, attributes: attributes, context:nil)
        return rect.size.height
    }
    
    ///用于時間轉(zhuǎn)換
    func dateStringFromTimestamp(timeStamp:NSString)->String
    {
        let ts = timeStamp.doubleValue
        let  formatter = NSDateFormatter ()
        formatter.dateFormat = "yyyy年MM月dd日 HH:MM:ss"
        let date = NSDate(timeIntervalSince1970 : ts)
         return  formatter.stringFromDate(date)
    }
    
}

2、UIView 擴展

extension UIView  {
   
    ///用于視圖的坐標
    func x()->CGFloat
    {
        return self.frame.origin.x
    }
    func right()-> CGFloat
    {
        return self.frame.origin.x + self.frame.size.width
    }
    func y()->CGFloat
    {
        return self.frame.origin.y
    }
    func bottom()->CGFloat
    {
        return self.frame.origin.y + self.frame.size.height
    }
    func width()->CGFloat
    {
        return self.frame.size.width
    }
    func height()-> CGFloat
    {
        return self.frame.size.height
    }
    
    func setX(x: CGFloat)
    {
        var rect:CGRect = self.frame
        rect.origin.x = x
        self.frame = rect
    }
    
    func setRight(right: CGFloat)
    {
        var rect:CGRect = self.frame
        rect.origin.x = right - rect.size.width
        self.frame = rect
    }
    
    func setY(y: CGFloat)
    {
        var rect:CGRect = self.frame
        rect.origin.y = y
        self.frame = rect
    }
    
    func setBottom(bottom: CGFloat)
    {
        var rect:CGRect = self.frame
        rect.origin.y = bottom - rect.size.height
        self.frame = rect
    }
    
    func setWidth(width: CGFloat)
    {
        var rect:CGRect = self.frame
        rect.size.width = width
        self.frame = rect
    }
    
    func setHeight(height: CGFloat)
    {
        var rect:CGRect = self.frame
        rect.size.height = height
        self.frame = rect
    }
    /// 顯示一個Alert
    class func showAlertView(title:String,message:String)
    {
        let alert = UIAlertView()
        alert.title = title
        alert.message = message
        alert.addButtonWithTitle("好")
        alert.show()

    }
   
}

3、NSDate擴展

extension NSDate {
    
    /**
     將特定日期轉(zhuǎn)成系統(tǒng)日期 如:2015-05-24 04:12:00 +0000
     - parameter string: 特定日期
     - returns: 系統(tǒng)日期
     */
    class func sinaDateToDate(string: String) -> NSDate? {
        // 創(chuàng)建datefromatter
        let df = NSDateFormatter()
        
        // 設置地區(qū)
        df.locale = NSLocale(localeIdentifier: "en")
        
        // 設置日期格式
        df.dateFormat = "EEE MMM dd HH:mm:ss zzz yyyy"
        
        return df.dateFromString(string)
    }
    
    ///  返回日期描述字符串
    ///
    ///     格式如下
    ///     -   剛剛(一分鐘內(nèi))
    ///     -   X分鐘前(一小時內(nèi))
    ///     -   X小時前(當天)
    ///     -   昨天 HH:mm(昨天)
    ///     -   MM-dd HH:mm(一年內(nèi))
    ///     -   yyyy-MM-dd HH:mm(更早期)
    func dateDescription() -> String {
        
        // 在ios中處理日期使用calendar
        let calendar = NSCalendar.currentCalendar()
        
        // 判斷是否是今天
        if calendar.isDateInToday(self) {
            
            // 獲取self和當前日期相差的秒數(shù)
            let delta = Int(NSDate().timeIntervalSinceDate(self))
            
            if delta < 60 {
                return "剛剛"
            }
            
            if delta < 60 * 60 {
                return "\(delta / 60) 分鐘前"
            }
            return "\(delta / 3600) 小時前"
        }
        
        var fmtString = "HH:mm"
        
        // 判斷是否是昨天
        if calendar.isDateInYesterday(self) {
            
            fmtString = "昨天 \(fmtString)"
            
        } else {
            
            // 比較年份
            let result = calendar.compareDate(self, toDate: NSDate(), toUnitGranularity: NSCalendarUnit.Year)
            
            if result == NSComparisonResult.OrderedSame {
                
                // 同一年
                fmtString = "MM-dd \(fmtString)"
                
            } else {
                
                // 更早期
                fmtString = "yyyy-MM-dd \(fmtString)"
            }
        }
        
        // 創(chuàng)建NSDateFormatter
        let fmt = NSDateFormatter()
        
        fmt.locale = NSLocale(localeIdentifier: "en")
        fmt.dateFormat = fmtString
        
        return fmt.stringFromDate(self)
    }
}

代碼片段

1箭昵、文件處理

class FileUtility: NSObject {
   
    class func cachePath(fileName:String)->String
    {
        var arr =  NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true)
        let path = arr[0] 
        return "\(path)/\(fileName)"
    }
    
    
    class func imageCacheToPath(path:String,image:NSData)->Bool
    {
       return image.writeToFile(path, atomically: true)
    }
    
    class func imageDataFromPath(path:String)->AnyObject
    {
        let exist = NSFileManager.defaultManager().fileExistsAtPath(path)
        if exist
        {
            //var urlStr = NSURL.fileURLWithPath(path)
            _ = NSData(contentsOfFile: path);
            //var img:UIImage? = UIImage(data:data!)
            //return img ?? NSNull()
            let img = UIImage(contentsOfFile: path)
            
            let url:NSURL? = NSURL.fileURLWithPath(path)
            let dd = NSFileManager.defaultManager().contentsAtPath(url!.path!)
            _ = UIImage(data:dd!)
            
            if img != nil {
                return img!
            } else {
                return NSNull()
            }
        }
        
        return NSNull()
    }
    
}

2税朴、支持縮放的Image

class YRImageZoomingView: UIScrollView,UIScrollViewDelegate {

    var imageView:UIImageView?
    var imageURL:String!
    let placeHolder:UIImage = UIImage(named:"avatar.jpg")!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        // Initialization code
        self.delegate = self
        
        
        self.imageView = UIImageView(frame:self.bounds)
        self.imageView!.contentMode = .ScaleAspectFit
        self.addSubview(self.imageView!)
        self.showsHorizontalScrollIndicator = false
        self.showsVerticalScrollIndicator = false
        self.backgroundColor = UIColor.clearColor()
        self.minimumZoomScale = 1;
        self.maximumZoomScale = 3;
     
        let doubleTap = UITapGestureRecognizer(target: self, action: "doubleTapped:")
        doubleTap.numberOfTapsRequired = 2;
        self.addGestureRecognizer(doubleTap);
        
    }

    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func doubleTapped(sender:UITapGestureRecognizer)
    {
        if self.zoomScale > 1.0
        {
            self.setZoomScale(1.0, animated:true);
        }
        else
        {
            let point = sender.locationInView(self);
            self.zoomToRect(CGRectMake(point.x-50, point.y-50, 100, 100), animated:true)
        }

    }
    
    
    func viewForZoomingInScrollView(scrollView: UIScrollView)->UIView?
    {
        return self.imageView
    }
    
    override func layoutSubviews()
    {
        super.layoutSubviews()
        self.imageView!.setImage(self.imageURL,placeHolder:placeHolder)
        
    }
    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect)
    {
        // Drawing code
    }
    */

}

3、圖片選擇器

import Foundation
import BSImagePicker
import Photos


/*
Copy the code snip below and paste in your UIViewController

---------------------
self!.TS_presentImagePickerController(
    maxNumberOfSelections: 6,
    select: { (asset: PHAsset) -> Void in
        print("Selected: \(asset)")
    }, deselect: { (asset: PHAsset) -> Void in
        print("Deselected: \(asset)")
    }, cancel: { (assets: [PHAsset]) -> Void in
        print("Cancel: \(assets)")
    }, finish: { (assets: [PHAsset]) -> Void in
        print("Finish: \(assets)")
    }, completion: { () -> Void in
        print("completion")
})
------------------
*/

public extension UIViewController {
    /**
     封裝一下 BSImagePickerViewController 家制,改變 UINavigationBar 的顏色
     
     - parameter maxNumberOfSelections: 最多選 多少個
     - parameter select:                選中的圖片
     - parameter deselect:              反選中的圖片
     - parameter cancel:                取消按鈕
     - parameter finish:                完成按鈕
     - parameter completion:            dimiss回掉完成
     */
    func ts_presentImagePickerController(maxNumberOfSelections maxNumberOfSelections: Int, select: ((asset: PHAsset) -> Void)?, deselect: ((asset: PHAsset) -> Void)?, cancel: (([PHAsset]) -> Void)?, finish: (([PHAsset]) -> Void)?, completion: (() -> Void)?) {

        let viewController = BSImagePickerViewController()
        viewController.maxNumberOfSelections = maxNumberOfSelections
        viewController.albumButton.tintColor = UIColor.whiteColor()
        viewController.cancelButton.tintColor = UIColor.whiteColor()
        viewController.doneButton.tintColor = UIColor.whiteColor()
        
        UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.Default, animated: false)
        self.bs_presentImagePickerController(viewController, animated: true,
            select: select, deselect: deselect, cancel: cancel, finish: finish, completion: {_ in
                TSApplicationManager.initNavigationBar()
                if let newCompletion = completion {
                    newCompletion()
                }
        })
    }
}

3正林、HTML 內(nèi)容的處理

說明:下面的使用場景:ios 9.1; xcode 7.1; swift 2.1

let html = <br>abac</br> //HTML內(nèi)容
// 下面這個方法很奇怪直接使用始終找不到
let data = html!.dataUsingEncoding(NSUTF32StringEncoding, allowLossyConversion: false)
do { //必須捕獲異常
     let atext = try NSAttributedString(data: data!, options: [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType], documentAttributes: nil)
     article_content.attributedText = atext
} catch {
      // 捕獲異常  }

to be continue ...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市颤殴,隨后出現(xiàn)的幾起案子觅廓,更是在濱河造成了極大的恐慌,老刑警劉巖诅病,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哪亿,死亡現(xiàn)場離奇詭異粥烁,居然都是意外死亡,警方通過查閱死者的電腦和手機蝇棉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門讨阻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人篡殷,你說我怎么就攤上這事钝吮。” “怎么了板辽?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵奇瘦,是天一觀的道長。 經(jīng)常有香客問我劲弦,道長耳标,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任邑跪,我火速辦了婚禮次坡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘画畅。我一直安慰自己砸琅,他們只是感情好,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布轴踱。 她就那樣靜靜地躺著症脂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪淫僻。 梳的紋絲不亂的頭發(fā)上诱篷,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音嘁傀,去河邊找鬼兴蒸。 笑死,一個胖子當著我的面吹牛细办,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蕾殴,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼笑撞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了钓觉?” 一聲冷哼從身側(cè)響起茴肥,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荡灾,沒想到半個月后瓤狐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞬铸,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年础锐,在試婚紗的時候發(fā)現(xiàn)自己被綠了嗓节。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡皆警,死狀恐怖拦宣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情信姓,我是刑警寧澤鸵隧,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站意推,受9級特大地震影響豆瘫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜菊值,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一靡羡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧俊性,春花似錦略步、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至典徊,卻和暖如春杭煎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卒落。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工羡铲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人儡毕。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓也切,卻偏偏與公主長得像,于是被迫代替她去往敵國和親腰湾。 傳聞我的和親對象是個殘疾皇子雷恃,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,520評論 25 707
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法费坊,內(nèi)部類的語法倒槐,繼承相關的語法,異常的語法附井,線程的語...
    子非魚_t_閱讀 31,587評論 18 399
  • 轉(zhuǎn)自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帥199207閱讀 8,500評論 3 93
  • 這個冬天讓我懷念的的十分之一,那一年把跨,夏人弓。在浦東的冬季里很難找到冬季的影子,依舊是节猿,我穿著單薄的外套票从,搭上...
    鴦花舞閱讀 252評論 0 1
  • 作為一枚懶癌患者,首先在這里說聲抱歉滨嘱。在去往鳳凰的時候峰鄙,好多朋友都說等著我的美圖以及游記,然后我這一拖就拖了n個多...
    七嶼PHOTO閱讀 963評論 8 18