2015年3月10日 星期二

swift程式碼小碎片筆記

//判斷是否為nil
//let image = UIImage(named: "foo")
if let image = UIImage(named: "foo") {
    //TODO: image != nil
} else {
    //TODO: image == nil
}

//用","將Array組成字串
let commaSeparatedArrayElements: String = ",".join(myArray)

//casting:用"as"來達成強轉型
var destinationViewController: Anyobject
let calcVC = destinationViewController as CalculatorViewController
//為了避免程式crash
if let calcVC = destinationViewController as? CalculatorViewController { ... }
//也可以用is來判斷型別
if destinationViewController is CalculatorViewController { ... }
//用括號強轉型
let button: AnyObject = UIButton.buttonWithType( UIButtonType.System)
let title = (button as UIButton).currentTitle

//取得substring
var s = "hello"
let index = advance(s.startIndex, 2) //取得"l"的index
s.splice("abc", index) //"heabcllo"
let startIndex = advance(s.startIndex, 1)
let endIndex = advance(s.startIndex, 6)
let substring = s[index..<endIndex] //"eabcl"

//雙問號代表"如果a不等於nil則,value = a,如果a為nil,則value = b"
let value = a ?? b 中的 a??b 代表 a != nil ? a! : b

//PropertyList就是plist,是定義為一個AnyObject的容器,這個容器只用來存放下列之中某一種(而且只能一種)Class:NSString、NSArray、NSDictionary、NSNumber、NSData、NSDate。

//String與NSString,Array與NSArray,Dictionary與NSDictionary可以直接casing所以as後面不用加問號
let string1 = "haha"
let string2:NSString = string1 as NSString

//Optional只是一種enum,在swift中沒有objective-C那種萬物皆空的nil(空指標),swift裡的nil也是一個值,但物值只要宣告出來就會指給它一個Optional<T>.None值,所以也可以直接判斷是否等於nil。

Conceptually it is like this (the <T> is a generic like as in Array<T>) ...
enum Optional<T> { 
 case None
 case Some(T) 
 }
let x: String? = nil
... is ... 
let x = Optional<String>.None 

let x: String? = “hello”
... is ... 
let x = Optional<String>.Some(“hello”) 

var y = x! 
... is ... 
switch x { 
 case Some(let value): y = value
 case None: // raise an exception 
}

//UIView的初始化有下列兩種,如果要用的話,請兩個都implement
init(frame: CGRect)  // initializer if the UIView is created in code
init(coder: NSCoder) // initializer if the UIView comes out of a storyboard

//這不是init方法,它只有在透過storyboard或nib去呼叫UIView時會被觸發,觸發的時機是在init(coder: NSCoder)之後,立刻執行
awakeFromNib

//在view座標系中,都要使用CGFloat
let cgf = CGFloat(aDoubleValue)

//view座標系
  • 原點在左上角
  • 單位是用point不是pixel
    • 如果你想知道當下的device中一個point等於幾個pixel,你可以呼叫UIView的var contentScaleFactor: CGPoint來查看(目前大部份是2)
  • 在view中繪圖(draw)的邊界
    • var bounds: CGPoint //這個view之內的座標系
  • 這個UIView的位置
    • var center: CGPoint  //這個view的中心點在superview中的座標
    • var frame: CGRect   //這個view在superview中的origin與size
//Never call drawRect!!
因為UIView會跟很多其他的view有關聯,所以在drawRect之前系統要先處理這些交互作用。
用下列的func代替,iOS會處理完這些事之後,再幫你呼叫drawRect()
setNeedsDisplay()
setNeedsDisplayInRect(regionThatNeedsToBeRedrawn: CGRect)

//swift字串截取
var string="1234567890" let index = advance(string.startIndex, 5) let index2 = advance(string.endIndex, -6); var range = Range<String.Index>(start: index2,end: index) var s1:String=string.substringFromIndex(index) var s2:String=string.substringToIndex(index2) var s3=string.substringWithRange(range) println(s1)//67890 println(s2)//1234 println(s3)//5

//closure
//在class中宣告為property
var didLinkTapped: ((chatroomName: String!) -> Void)?
//在要執行的時機點呼叫
self.didLinkTapped!(chatroomName: chatroomName)
//在你對外的方法中傳入實做的部份
init(id: String, text: String, didLinkTapped: ((chatroomName: String!) -> Void)?) {
        super.init(id: id)
        
        self.didLinkTapped = didLinkTapped
}

//dispatch_after in swift
let delayTime = dispatch_time(DISPATCH_TIME_NOW,
            Int64(sec * Double(NSEC_PER_SEC)))
        dispatch_after(delayTime, dispatch_get_main_queue()) { () -> Void in
            self.removeFromSuperview()

        } //sec要設為double

//enum轉數字
yourEnum.rawValue

//加入一個AlertView,按下任何地方即離開
let alertController = UIAlertController(
            title: NSLocalizedString("Error", comment: "Error"),
            message: error?.localizedDescription,
            preferredStyle: .Alert)
        let closeAction = UIAlertAction(title: NSLocalizedString("CLOSE", comment: "Close"), style: .Cancel) {
            (action) in
            alertController.dismissViewControllerAnimated(true, completion: nil)
        }
        alertController.addAction(closeAction)
        self.presentViewController(alertController, animated: true) {
            alertController.view.userInteractionEnabled = true
            if let window = alertController.view.window {
                var tapGestureRecognizer: UITapGestureRecognizer?
                tapGestureRecognizer = window.tapped() {
                    (sender: UITapGestureRecognizer) -> Void in
                    if sender.state == UIGestureRecognizerState.Ended {
                        let location: CGPoint = sender.locationInView(alertController.view)
                        // check tap point in alert window
                        if alertController.view.pointInside(location, withEvent: nil) == false {
                            alertController.dismissViewControllerAnimated(true, completion: nil)
                        }
                    }
                    window.removeGestureRecognizer(tapGestureRecognizer!)
                }
                tapGestureRecognizer?.cancelsTouchesInView = false
            }

        }

//UIImageView rotation extension
import Foundation

extension UIImageView {
    func rotate360WithDuration(duration: Double, repeatCount: Float) {
        var fullRotation: CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation")
        fullRotation.fromValue = 0
        fullRotation.toValue = ((360 * M_PI) / 180)
        fullRotation.duration = duration
        fullRotation.speed = 2.0
        if repeatCount == 0 {
            fullRotation.repeatCount = MAXFLOAT
        } else {
            fullRotation.repeatCount = repeatCount
        }
        self.layer.addAnimation(fullRotation, forKey: "360")
    }
    
    func stopAnimation() {
        self.layer.removeAllAnimations()
    }

}

//更換UIBarButtonItem
let loadingImageView = UIImageView(image: UIImage(named: "IOS_loading_static") )
loadingImageView.rotate360WithDuration(2.0, repeatCount: 0)
let barButton = UIBarButtonItem(customView: loadingImageView)

self.navigationItem.rightBarButtonItem = barButton

//NSUserDefault
let defaults = NSUserDefaults.standardUserDefaults()
//read
let plist: AnyObject = defaults.objectForKey(String)
//write
defaults.setObject(AnyObject, forKey: String)
//大部份會自動儲存,但你可以用這個判斷來處理少部份的情況
if !defaults.synchronize() { /*TODO:error handling*/}

//在enum中使用switch
public enum LogLevel: Int {
    case Error = 0
    case Warning
    case Info
    case Debug
    case Verbose
    
    var prefix : String {
        get {
            switch self {
            case .Error: return "E"
            case .Warning:  return "W"
            case .Info:     return "I"
            case .Debug:    return "D"
            case .Verbose:  return "V"
            }
        }
}
}

//回到上一頁(不管是present或push出來的vc)
dynamic func popToPrevious() {
        logInfo(TAG, "popToPrevious")
        if self.parentNavigationController != nil {
            //self.parentNavigationController是自己創的,看有沒有被給值
            self.parentNavigationController?.popViewControllerAnimated(true)
        } else if let navigation = self.navigationController {
            navigation.popViewControllerAnimated(true)
        } else if self.presentingViewController != nil
            && (self.presentingViewController is NewLoginViewController) == false {
                self.dismissViewControllerAnimated(true, completion: nil)
        }

    }

//在textView中加入圖片
var textAttachment = NSTextAttachment()
        textAttachment.image = UIImage.scaleToSize(image, size: CGSize(width: UIMessageTheme.AvatarTitle.size, height: UIMessageTheme.AvatarTitle.size))
        let imageString = NSAttributedString(attachment: textAttachment)
        var mas = NSMutableAttributedString(attributedString: inputTextField.attributedText)
        mas.replaceCharactersInRange(NSMakeRange(mas.length, 0), withAttributedString: imageString)

        self.inputTextField.attributedText = mas;

//偵測status bar點擊事件(寫在AppDelegate中)
public override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        let touchesSet = touches as NSSet
        if let touch = touchesSet.anyObject() as? UITouch {
            let location = touch.locationInView(self.window)
            //你偵測的高度
            if location.y > 0 && location.y < 20 {
                self.touchStatusBar()
            }
        }
    }
    
    private func touchStatusBar() {
        NSNotificationCenter.defaultCenter().postNotificationName(DefaultConfig.STATUS_BAR_CLICK, object: nil)

    }

//設定UITextView的文字邊界
self.yourTextView.textContainerInset = UIEdgeInsets(top: 10.5, left: 9, bottom: 9.5, right: 15)

//加上模糊效果
//should import UIKit
func insertBlurView (view: UIView,  style: UIBlurEffectStyle) {
    view.backgroundColor = UIColor.clearColor()
    var blurEffect = UIBlurEffect(style: style)
    var blurEffectView = UIVisualEffectView(effect: blurEffect)      
    blurEffectView.frame = view.bounds
    view.insertSubview(blurEffectView, atIndex: 0)
}

//取得現在時間(原來是用[NSDate date])
let date = NSDate()

//去掉空尾空白和換行
let dataString = string.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

//data to string (utf8)
let data = command.dataUsingEncoding(NSUTF8StringEncoding)

//data to string (utf8)
let string = String(data: data!, encoding: NSUTF8StringEncoding)


//移除present出來的viewController
func dismissViewController(viewController: UIViewController, animated: Bool) {
    if viewController.isBeingDismissed() || viewController.isBeingPresented() {
        dispatch_async(dispatch_get_main_queue()) {
            dismissViewController(viewController, animated: animated)
        }
        return
    }
 
    if viewController.presentingViewController != nil {
        viewController.dismissViewControllerAnimated(animated, completion: nil)
    }
}

// UIColor Extension
    // 自定義color
    class func styleDarkColor() -> UIColor {
        return UIColor.hexToColor(0xFF008CEE)
    }
    
    class func hexToColor(hex: UInt32) -> UIColor {
        return UIColor(red: CGFloat((hex & 0xFF0000) >> 16) / 255, green: CGFloat((hex & 0xFF00) >> 8) / 255 ,
            blue: CGFloat(hex & 0xFF) / 255 , alpha: CGFloat((hex & 0xFF000000) >> 24) / 255)
    }
    
    // 十六進制String轉UIColor
    class func hexStringToColor(hexString: String) -> UIColor {
        var rgbValue: UInt32 = 0
        let scanner = NSScanner(string: hexString)
        scanner.scanLocation = 0
        scanner.scanHexInt(&rgbValue)
        return UIColor(red: CGFloat((rgbValue & 0xFF0000) >> 16)/255.0,
            green: CGFloat((rgbValue & 0xFF00) >> 8)/255.0,
            blue: CGFloat(rgbValue & 0xFF)/255.0,
            alpha: 1.0)
    }
    
    // 以這個顏色產生一個長度為1的小圖(在button好用)
    func tinyImage() -> UIImage {
        let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        CGContextSetFillColorWithColor(context, self.CGColor)
        CGContextFillRect(context, rect)
        
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return image
    }

//改變navigationController的顏色
    //navigation bar
    navigationController.navigationBar.barTintColor = UIColor.yellowColor()
    //navigation bar text
    navigationController.navigationBar.titleTextAttributes =  [UITextAttributeTextColor: UIColor.yellowColor()]

//改變tabBarController的顏色
    //tab bar
    tabBarController.tabBar.barTintColor = UIColor.yellowColor()
    //tab bar text
    tabBarController.tabBar.tintColor = UIColor.yellowColor()

//不讓app進入休眠

UIApplication.sharedApplication().idleTimerDisabled = true
同時最好去實作appDelegate裡面的func applicationWillResignActive(application: UIApplication) { ... }
把可以發生的中斷事件都處理好,例如phone call、SMS等。

//客製化UITextField的輸入鍵盤
    //換掉inputView就行
        yourTextField.inputView = yourPickerView
    //換回來系統預設的
        yourTextField.inputView = nil
        yourTextField.reloadInputViews()
    //這是換掉鍵盤上面那一條控制用的Bar

        yourTextField.inputAccessoryView = yourCustomAccessoryView

//使用其他預設的鍵盤-改變UIKeyboardType
self.phoneTextField.keyboardType = .PhonePad

self.emailTextField.keyboardType = .EmailAddress

// UIButton預設是置中對齊,如果要改成向左就這樣設

yourButton.contentHorizontalAlignment = .Left

//object to data
let yourViewToData = NSKeyedArchiver.archivedDataWithRootObject(yourView)
if let yourViewFromData = NSKeyedUnarchiver.unarchiveObjectWithData(yourViewToData) as? UIView {
  // Do what you want with your view
}

沒有留言:

張貼留言