Swift Reusable Code Segment

可复用的swift代码段。为什么用英文做标题?为了突出“复用”

文章的目的:记录经常使用的代码块方便复用
更新次数:将会不定期持续更新
内容来源:有些是从优秀开源代码中摘要的,有些是自己写的。在此不多做说明。
文章权限:欢迎收藏转载,但请勿用于商业用途

一定程度上说,编写代码是一件重复性很高的工作。当然我并不是说写出优质的代码是一件容易的事情,相反我想表达的是我们在大多数情况下会重复以前开发过的内容。所以代码的复用就显得尤为重要。说到这里我不得不分享一下,最近看到的一篇关于面向对象设计原则的文章。虽然是以Android为描述语言,但思路是相通的不耽误学习。

面向对象的6个基本原则:

  • 1、单一职责原则:一个类中应该是一组相关性很高的函数、数据的封装。
  • 2、开闭原则:简单的说就是,一个类只对扩展开放,对修改关闭。
  • 3、里氏替换原则:所有引用基类的地方必须能透明地使用其子类的对象,简单的说就是父类能够使用的地方子类一定能够使用。
  • 4、接口隔离原则:客户端不应该依赖它不需要的接口。可以理解为一个方法中应该避免过多的接口依赖。
  • 5、依赖倒置原则:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。既面向接口编程,或者面向抽象类编程。
  • 6、迪米特原则:也叫最少知识原则。意思是,一个对象应该对其他对象有最少的了解。可以理解为,一连串的相关处理事件应该抽离封装出来。对于调用这个封装函数的调用者,封装代码内部逻辑是透明的。 以上六点是java面向对象的原则。其他语言应该也是适用的。
    如果感兴趣可以查看原文:面向对象的六个基本原则

好了偏题结束。正式"Resualbe"部分。

基本数据类型扩展

1、String 扩展

extension String {

    ///用于计算字符串在高度。
    ///例如,当需要动态计算TableVIewCell高度的时候,需要根据某个Label的内容String的长度来调整cell的高度,让其能够全部显示内容。
    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
    }
    
    ///用于时间转换
    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 {
    
    /**
     将特定日期转成系统日期 如:2015-05-24 04:12:00 +0000
     - parameter string: 特定日期
     - returns: 系统日期
     */
    class func sinaDateToDate(string: String) -> NSDate? {
        // 创建datefromatter
        let df = NSDateFormatter()
        
        // 设置地区
        df.locale = NSLocale(localeIdentifier: "en")
        
        // 设置日期格式
        df.dateFormat = "EEE MMM dd HH:mm:ss zzz yyyy"
        
        return df.dateFromString(string)
    }
    
    ///  返回日期描述字符串
    ///
    ///     格式如下
    ///     -   刚刚(一分钟内)
    ///     -   X分钟前(一小时内)
    ///     -   X小时前(当天)
    ///     -   昨天 HH:mm(昨天)
    ///     -   MM-dd HH:mm(一年内)
    ///     -   yyyy-MM-dd HH:mm(更早期)
    func dateDescription() -> String {
        
        // 在ios中处理日期使用calendar
        let calendar = NSCalendar.currentCalendar()
        
        // 判断是否是今天
        if calendar.isDateInToday(self) {
            
            // 获取self和当前日期相差的秒数
            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)"
            }
        }
        
        // 创建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 内容的处理

说明:下面的使用场景:ios 9.1; xcode 7.1; swift 2.1

let html = <br>abac</br> //HTML内容
// 下面这个方法很奇怪直接使用始终找不到
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 ...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,566评论 25 707
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,293评论 18 399
  • 转自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帅199207阅读 8,384评论 3 93
  • 这个冬天让我怀念的的十分之一,那一年,夏。在浦东的冬季里很难找到冬季的影子,依旧是,我穿着单薄的外套,搭上...
    鸯花舞阅读 244评论 0 1
  • 作为一枚懒癌患者,首先在这里说声抱歉。在去往凤凰的时候,好多朋友都说等着我的美图以及游记,然后我这一拖就拖了n个多...
    七屿PHOTO阅读 908评论 8 18