Swift 常用技巧

  1. 使xib中的控件距頂部預(yù)留出導(dǎo)航欄的寬度:
    在swift文件中的viewDidLoad方法中增加以下語句:
    self.navigationController?.navigationBar.translucent = false

  2. 防止循環(huán)引用:
    所謂循環(huán)引用掰读,就是指兩個類互相持有對方類型的變量名扛,從而導(dǎo)致內(nèi)存無法正確回收的情況陈醒,例如:

class A {var b : B?}
class B {var a : A?}

解決辦法為:在某一方的變量定義前加上weak抚岗,表示不希望該對象主動去持有對方的變量,例如:

class A {var b : B?}
class B {weak var a : A?}

這樣的話鱼鼓,當(dāng)A被釋放之后拟烫,B就不會再引用對象A,從而兩個對象都可以正確釋放

  1. 字符串與變量拼接:
println("location = \(recognizer.locationInView(view).x)")
  1. 在一個Label中設(shè)置多種文字顏色:
let length = valueString.characters.count
let mutableString = NSMutableAttributedString(string: "colored String: 
\(valueString)")
mutableString.addAttribute(NSFontAttributeName, value: UIFont.systemOfSize(25), range: NSMakeRange(0, length))
mutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.yellowColor(), range: NSMakeRange(0, length))
textLabel.attributedText = mutableString
  1. 控件自適應(yīng)屏幕大衅尽:
let screenWidth = UIScreen.mainScreen().applicationFrame.maxX                 //獲取屏幕寬度
let screenHeight = UIScreen.mainScreen().applicationFrame.maxY                //獲取屏幕高度
view.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)     //設(shè)置View的Frame尺寸
  1. 為控件設(shè)置圓角和邊框:
//為控件設(shè)置圓角
view.layer.masksToBounds = true     
//view.clipsToBounds = true
view.layer.cornerRadius = 10

 //設(shè)置返回按鈕的點(diǎn)擊事件
view.layer.borderColor = UIColor.whiteColor().CGColor
view.layer.borderWidth = 5.0
  1. ViewController之間跳轉(zhuǎn):
let targetView = TargetViewController(nibName: "TargetViewController"
, bundle: nil)
self.presentViewController(targetView, animated: true, completion: nil)     //打開新的頁面(不可返回)
self.navigationController?.pushViewController(targetView, animated: true)   //打開下級頁面(可以返回)
  1. ViewController返回上一級或關(guān)閉:
if (self.navigationController?.popViewControllerAnimated(true) == nil) {     //優(yōu)先返回上級頁面
    self.dismissViewControllerAnimated(true, completion: nil)               //若無法返回上級頁面硕淑,則關(guān)閉此頁面
}
  1. 設(shè)置鍵盤返回按鈕的樣式和點(diǎn)擊事件:
    鍵盤上返回按鈕的樣式,是根據(jù)彈出鍵盤的TextField來決定的
    修改的方式是在xib中選中textField嘉赎,設(shè)置Return Key的類型即可置媳,如下圖
    設(shè)置返回按鈕的樣式

    若需要設(shè)置返回按鈕的點(diǎn)擊事件,則使ViewController繼承UITextFieldDelegate公条,并實(shí)現(xiàn)textFieldShouldReturn方法即可
class TestViewController: UIViewController, UITextFieldDelegate{
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self 
    }

    //設(shè)置返回按鈕的點(diǎn)擊事件
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        textField.resignFirstResponder()           //關(guān)閉鍵盤
        //...執(zhí)行相應(yīng)操作
        return true
    }
}
  1. 取消手勢其他手勢的沖突:
class HBFamilyViewController: UIViewController, UIGestureRecognizerDelegate {
     override func viewDidLoad() {
        panGesture = UIPanGestureRecognizer()
        panGesture.addTarget(self, action: Selector("handlePanGesture:"))
        panGesture.delegate = self
     }

     //設(shè)置允許手勢與其他手勢共存
     func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer        
        otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}
  1. 判斷TableView是否劃動到頂部:
tableView.contentOffset.y == 0
  1. 在Swift中使用全局變量:
    首先在AppDelegate中定義一個變量拇囊,例如:
var globalString: String?

然后在其他類中獲取到AppDelegate,并使用該變量即可赃份,例如:

let app = UIApplication.sharedApplication().delegate as! AppDelegate
app.globalString = "test"
  1. 在Swift中使用泛型:
    Swift中的泛型可以是任意類型寂拆,但是必須要在類/方法定義的時候指定<T>
class HBCacheManager<T>: NSObject {
    var databaseDic = Dictionary <String, T> ()
}
  1. 禁止TableView上下劃動:
    在xib文件中將bounces的復(fù)選框去掉

  2. 從xib文件中加載UIView:

let myView = NSBundle.mainBundle().loadNibNamed("MyView" , owner: nil, options: nil).firstas! MyView
myView.frame = CGRectMake(0, 0, width, height)
parentView.addSubview(missionView)

注意:目標(biāo)xib文件需要設(shè)置Class屬性為自定義的UIView文件,如下:


設(shè)置UIView的類型
  1. ImageView圖片拉伸變形問題的解決:
    修改以下屬性:

    修改紅框中的屬性

    其中:Aspect Fill屬性用于解決圖片拉伸問題
    Clip Subviews用于解決圖片超出控件邊緣的問題

  2. 為界面增加毛玻璃效果:
    下面的控件拖出來直接使用即可

    使用UIVisualEffectView

  3. NavigationBar背景透明:

self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.translucent = true
  1. 設(shè)置ViewController和xib文件的關(guān)聯(lián):
    首先設(shè)置xib文件的File’s Owner:

    設(shè)置FileOwner

    然后右鍵點(diǎn)擊File’s Owner抓韩,指定xib文件的View:
    指定View

  2. 避免xib設(shè)置的控件布局錯亂的技巧:
    在UIViewController中:
    在viewDidLoad方法中創(chuàng)建控件和獲取數(shù)據(jù)
    在viewDidLayoutSubviews方法中設(shè)置控件的Frame

在UIView中:
在awakeFromNib中創(chuàng)建控件
在layoutSubviews方法中設(shè)置控件的Frame
*注意纠永!由于layoutSubviews方法很可能會被多次調(diào)用,所以不要在該方法中創(chuàng)建控件谒拴!

  1. 自動布局控件的優(yōu)先級:
    Content Hugging Priority:控件防止變大的優(yōu)先級
    Content Compression Resistance Priority:控件防止變小的優(yōu)先級

對于UILabel和UIButton等控件尝江,在顯示的時候可以根據(jù)里面的內(nèi)容動態(tài)設(shè)置大小
但是,若一行中并排放置兩個Label英上,并要求兩個Label的總長度能夠占滿屏幕的話
由于Label的長度是根據(jù)里面的文字動態(tài)變化的炭序,那么就會出現(xiàn)這樣的問題:
1、若兩個Label的長度總和小于屏幕寬度苍日,那么由哪個Label變寬來占滿屏幕惭聂?
2、若兩個Label的長度總和大于屏幕寬度相恃,那么由哪個Label變窄來讓出屏幕辜纲?

這樣就需要通過這兩個屬性來進(jìn)行設(shè)置了
1、若兩個Label的長度總和小于屏幕寬度拦耐,那么由Content Hugging Priority數(shù)值較小的Label變寬來占滿屏幕
2耕腾、若兩個Label的長度總和大于屏幕寬度,那么由Content Compression Resistance Priority數(shù)值較小的Label變窄來讓出屏幕

  1. 設(shè)置UIView的位置:
    如果是固定設(shè)置UIView的位置杀糯,則修改UIView的.center
    如果是臨時改變UIView的位置扫俺,則修改UIView的.transform

  2. TableView動態(tài)設(shè)置Cell高度:
    在viewDidLoad方法中將tableView設(shè)成動態(tài)高度,如下:

tableView.estimatedRowHeight = 100      //這個參數(shù)用于提升性能固翰,
tableView.rowHeight = UITableViewAutomaticDimension

如果cell使用xib來定義狼纬,那么首先需要確保xib中各控件的頂部羹呵、底部和高度都設(shè)置了約束
其次,如果在代碼中為cell中某個控件中添加了子控件畸颅,并且想要修改該控件的高度約束的話
那么絕對不要直接修改高度的約束担巩!而是要手動調(diào)用updateConstraintsIfNeeded方法,并在該方法中設(shè)置控件高度的約束没炒,如

class HBInteractionTableViewCell: UITableViewCell {
    @IBOutlet weak var galleryView: UIView!
    @IBOutlet weak var galleryHeight: NSLayoutConstraint!

    func setImage(imageView: UIImageView) {
        galleryView.addSubview(imageView)

        //注意涛癌!下面這行代碼一定不能寫在這里,否則cell不會自動更新其他控件的高度
        //galleryHeight.constant = imageView.height
 
        //立即觸發(fā)更新布局
        self.updateConstraintsIfNeeded()
    }

    override func updateConstraintsIfNeeded() {
        galleryHeight.constant = imageSetView.height     //修改高度約束的代碼要寫在這里
        super.updateConstraintsIfNeeded()
    }
}
  1. 去掉float后面的.0:
NSString(format: "%.0f", lastUploadDate.timeIntervalSince1970 * 1000) as String
  1. 調(diào)用bundle中的文件:
    例如bundle的名稱為pic.bundle送火,里面有名為save.jpg和cancel.jpg兩個文件
    則調(diào)用方法為UIImage(named: "pic.bundle/cancel")

  2. 獲取tableView中cell在整個頁面中的位置:

let rectInTableView = tableView.rectForRowAtIndexPath(indexPath)
let cellFrame = tableView.convertRect(rectInTableView, toView: self.view)
  1. 在View上(如TextField)增加Loading遮罩:
func addIndicator(view: UIView) {    
  let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .Gray)    
  view.addSubview(activityIndicator)
  activityIndicator.frame = view.bounds      
  activityIndicator.startAnimating()           
  //activityIndicator.removeFromSuperview()   //當(dāng)執(zhí)行完畢后拳话,調(diào)用此方法移除遮罩
}
  1. 在程序中使用自定義字體:
    首先將.ttf文件拷貝到工程的任意目錄下,點(diǎn)選該文件种吸,在右側(cè)Target Membership中選中當(dāng)前項(xiàng)目弃衍,

    一定要注意選中紅框中的內(nèi)容

    然后在xib中查看是否有這個字體,如果有則直接可以使用
    如果沒有坚俗,則在Finder中打開這個字體镜盯,右鍵 > 使用字體冊打開,點(diǎn)擊【安裝字體】猖败,然后在新打開的窗口中可以看到字體名稱:
    紅框內(nèi)即是字體名稱

  2. 生成純色的圖片(可用于Button的背景圖):

extension UIImage {
    /** 源于色彩的UIImage速缆,可自定義size */
    class func imageWithColor(color: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1), size: CGSize = CGSizeMake(1, 1)) -> UIImage {
        let rect = CGRectMake(0, 0, size.width, size.height)

        //開啟一個圖形上下文     
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)

        //獲取圖形上下文
        let context = UIGraphicsGetCurrentContext()
        CGContextSetFillColorWithColor(context, color.CGColor)
        CGContextFillRect(context, rect)              

        //獲取圖像
        let image = UIGraphicsGetImageFromCurrentImageContext()               

        //關(guān)閉上下文      
        UIGraphicsEndImageContext();               
        return image;
    }
}```

30. **為類定義delegate(代理):**

@objcpublic protocol MyDelegate {
func requiredFunc()
optional func optionalFunc()
}


31. **FirstResponder的使用:**
當(dāng)需要為某個控件或事件注冊響應(yīng),但又不知道注冊給誰的時候
可以注冊給FirstResponder恩闻,然后在程序中將某個控件注冊為響應(yīng)者艺糜,例如:
```textField.becomeFirstResponder()```
這樣,當(dāng)事件被發(fā)出后幢尚,textField就可以第一時間響應(yīng)該事件

32. **為TableViewCell增加向右箭頭:**
設(shè)置TableViewCell的Accessory屬性為**Disclosure Indicator**破停,如下圖:
![](http://upload-images.jianshu.io/upload_images/2250628-b5642c0af817e32b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

33. **struct和class的區(qū)別:**
struct里面的變量和常量默認(rèn)是全局訪問的,而class里面的變量和常量默認(rèn)是私有的
如果想要定義一個全局可用的靜態(tài)常量尉剩,則可以定義在struct**里面**真慢,但必須要定義在class**外面**
因此,我們?nèi)绻胍ㄟ^**類名.變量名**的方式來調(diào)用一個全局靜態(tài)變量的話理茎,就需要把這個變量定義在struct中

34. **解決iOS界面設(shè)計和開發(fā)字體大小不一致的問題:**
iOS開發(fā)時晤碘,所用的字體單位均為pt,即point
# 
之所以用pt而不是用px功蜓,是因?yàn)椴煌脑O(shè)備屏幕像素密度(PPI)不同
在非Retina屏上宠蚂,像素密度為72PPI式撼,而在Retina屏上,像素密度則為144PPI
由于Retina屏的像素密度比非Retina屏要高一倍求厕,因此同樣的像素值著隆,在Retina屏上顯示的大小就要小一半
因此扰楼,若將文字大小設(shè)成20px,在Retina屏上顯示的大小就比非Retina屏上的大小要小一倍
# 
因此美浦,文字的pt值弦赖,是保證文字在不同的屏幕上都顯示為同樣的大小
在不同的設(shè)備屏幕上,1pt顯示的實(shí)際像素浦辨,是由屏幕的PPI決定的
在Retina屏上蹬竖,1pt對應(yīng)的像素值為1px。如果設(shè)備是Retina屏流酬,則為1pt=2px
由于目前iOS主流設(shè)備均為Retina屏币厕,因此設(shè)計時用144 PPI,就能保證設(shè)計出的pt數(shù)值與開發(fā)時的pt數(shù)值完全一致芽腾。

35. **解決UITextView左側(cè)和上方空白的問題:**

descriptTextView.contentInset = UIEdgeInsets(top: -8, left: -5, bottom: 0, right: 0)


36. **解決隱藏NavigationBar時動畫錯亂的問題:**
不要直接設(shè)置```navigationController.hidden = true```旦装,而是調(diào)用下面的方法:

self.navigationController?.setNavigationBarHidden(true, animated: true)


37. **刪除不用的Profile和證書:**
**證書:**打開鑰匙串訪問,直接刪除即可
**Profile:**打開~/Library/MobileDevice/Provisioning Profiles摊滔,刪除所有文件
*注:~表示當(dāng)前用戶的目錄

38. **解決cell中控件尺寸始終不正確的問題:**

self.contentView.setNeedsLayout()
self.contentView.layoutIfNeeded()


39. **為工具欄和NavigationBar預(yù)留出空間:**
工具欄的高度為16
NavigationBar的高度為48

40. **代碼獲取TabbarController當(dāng)前顯示的ViewController:**

let navController = self.selectedViewController as! UINavigationController
let viewController = navController.topViewController!


41. **為UIColor增加透明效果:**

color.colorWithAlphaComponent(0.7)


42. **向ScrollView中添加控件:**

let imageSpaceX:CGFloat = 5.0
let imageSizeX:CGFloat = 50
let imageSizeY:CGFloat = 50

var originX:CGFloat = 0
for index in 0...imageViewList.count-1 {
let view = scrollView.subviews[index]
view.frame = CGRectMake(originX, 0, imageSizeX, imageSizeY)
originX += (imageSizeX + imageSpaceX)
}

scrollView.contentSize = CGSize(width: originX, height: scrollView.frame.height)


43. **改變UITextField中placeholder文字的顏色:**

content.setValue(UIColor.darkGrayColor(), forKeyPath: "_placeholderLabel.textColor")


44. **使UILabel中文字自動適配控件大小并居中顯示:**

originalPriceLabel.adjustsFontSizeToFitWidth = true
originalPriceLabel.baselineAdjustment = UIBaselineAdjustment.AlignCenters


45. **為UILabel中文字增加刪除線**

let attributedText = NSAttributedString(string: "( self.packageInfo.costPrice )", attributes: [NSStrikethroughStyleAttributeName: 2])
originalPriceLabel.attributedText = attributedText


**46阴绢、為UIView增加在xib中可編輯的屬性**

extension UIView {
@IBInspectable var cornerRadius: CGFloat { //重點(diǎn)是@IBInspectable
get {
return layer.cornerRadius
}

    set {            
      layer.cornerRadius = newValue            
      layer.masksToBounds = newValue > 0        
    }
}

}




**附錄:一些常用的開發(fā)技巧:**
奇淫巧技:http://www.cocoachina.com/ios/20141231/10783.html
自定義界面切換效果:http://blog.csdn.net/zhuzhihai1988/article/details/39228955
葉孤城博客:http://www.reibang.com/users/b82d2721ba07/latest_articles
優(yōu)秀開源項(xiàng)目:http://www.cocoachina.com/swift/20150126/11016.html
PHAsset的用法:http://kayosite.com/ios-development-and-detail-of-photo-framework.html/comment-page-1

獲取圖片的背景顏色:http://www.csdn.net/article/2015-01-12/2823525-swiftcolorart
LTBouncyPlaceHolder:https://github.com/nixzhu/dev-blog/blob/master/2014-06-12-LTBouncyPlaceholder.md

http://my.oschina.net/u/2340880/blog/538356
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市艰躺,隨后出現(xiàn)的幾起案子呻袭,更是在濱河造成了極大的恐慌,老刑警劉巖描滔,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棒妨,死亡現(xiàn)場離奇詭異,居然都是意外死亡含长,警方通過查閱死者的電腦和手機(jī)券腔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拘泞,“玉大人纷纫,你說我怎么就攤上這事∨汶纾” “怎么了辱魁?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長诗鸭。 經(jīng)常有香客問我染簇,道長,這世上最難降的妖魔是什么强岸? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任锻弓,我火速辦了婚禮,結(jié)果婚禮上蝌箍,老公的妹妹穿的比我還像新娘青灼。我一直安慰自己暴心,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布杂拨。 她就那樣靜靜地躺著专普,像睡著了一般。 火紅的嫁衣襯著肌膚如雪弹沽。 梳的紋絲不亂的頭發(fā)上檀夹,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機(jī)與錄音贷币,去河邊找鬼击胜。 笑死,一個胖子當(dāng)著我的面吹牛役纹,可吹牛的內(nèi)容都是我干的偶摔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼促脉,長吁一口氣:“原來是場噩夢啊……” “哼辰斋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瘸味,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤宫仗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后旁仿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藕夫,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年枯冈,在試婚紗的時候發(fā)現(xiàn)自己被綠了毅贮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡尘奏,死狀恐怖滩褥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情炫加,我是刑警寧澤瑰煎,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站俗孝,受9級特大地震影響酒甸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赋铝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一插勤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦饮六、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至臂外,卻和暖如春窟扑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背漏健。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工嚎货, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蔫浆。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓殖属,卻偏偏與公主長得像,于是被迫代替她去往敵國和親瓦盛。 傳聞我的和親對象是個殘疾皇子洗显,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

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