AutoLayout

只要確定好下面的參數,autoLayout就不會跑警告

  1. x
  2. y
  3. width
  4. height

AlertController

  1. 新增AlertController
    • .ActionSheet可藉由點警告視窗外面而取消
    • .alert不可藉由點警告視窗外面而取消
  2. 如果需要”OK”等選項的話,新增UIAction (.alert必做,不然會回不去)
  3. 將UIAction放置到AlertController上
  4. present
1
2
3
4
let myAlert = UIAlertController(title: "Please enter something", message: nil, preferredStyle: .alert)
let myAction = UIAlertAction(title: "OK", style: .default, handler:nil)
myAlert.addAction(myAction)
present(myAlert, animated: true, completion: nil)

嘗試加入文字框

1
2
3
4
5
let myAlert = UIAlertController(title: "Add New Task", message: nil, preferredStyle: .alert)
myAlert.addTextField {
  (textfield:UITextField) in
  textfield.placeholder = "Add New Task'"
}

嘗試對加入的UIAction執行一些動作

1
2
3
4
5
6
7
let ok = UIAlertAction(title: "OK", style: .default){
	(action) in
  // action是UIAlertAction
  // 在下面填入想要執行的動作
  ...
  ...
}

讓鍵盤自動彈出

在可輸入的View中(Ex: textfield),會有becomeFirstResponder()方法

PickerView

選中某一列後立刻執行某動作

複寫

1
2
3
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
	chooseColor = colorArray[row]
}

得知目前是選中哪一列

call function,並指定是哪個Component

1
myPickerView.selectedRow(inComponent: 0)

更為簡單的DatePickerView

若想得知DatePickerView所擷取到的日期或時間只要使用

1
let date = myDatePicker.date

一行即可,其他的都是date格式的問題。
DatePickerView的樣式可以從storyBoard中選擇。

播放影片

流程

  1. 找到播放影片URL
  2. 初始化AVPlayer(將URL放進去)
  3. 初始化AVPlayerViewController
  4. 將AVPlayerController的player設成剛剛的AVPlayer
  5. present並播放
1
2
3
4
5
6
7
8
9
guard let path = Bundle.main.url(forResource: "HipHop", withExtension: "mp4") else {
	return
}

let videoPlayer = AVPlayer(url: path)
let videoPlayerController = AVPlayerViewController()
videoPlayerController.player = videoPlayer
present(videoPlayerController, animated: true, completion: nil)
videoPlayer.play()

重複播放

不同於播放音樂可以簡單設置loop,重複播放影片是要傾聽影片播完後所發送的notification。

監聽播放完成notification

1
2
3
4
5
6
7
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.playerDidReachEnd(notification:)), name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: nil)

// 監聽function
func playerDidReachEnd(notification:Notification){
    videoPlayer?.currentItem?.seek(to: kCMTimeZero)
    videoPlayer?.play()
}

錄影

照相

  1. 在info.plist設定照相權限
  2. 產生image picker Controller
  3. 設定 sourceType
  4. 設定delegate屬性,決定照相完畢後要做什麼
  5. 推出image Picker

這邊要特別注意,模擬器是沒有camera的,所以若要用模擬器最好先檢查。

照相權限

照相權限

1
2
3
4
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .camera
imagePicker.delegate = self
present(imagePicker, animated:true, completion:nil)

delegate寫法

1
2
3
4
5
6
7
8
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
  guard let image = info[UIImagePickerControllerMediaURL] as? UIImage{
    print("Cannot get picture url")
    return
  }
  myImageView.image = image
  dismiss(animated: true, completion: nil)
}

其他實用方法

若想存檔可使用下方程式碼

1
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)

若想直接從已拍照圖庫裡面選擇圖片,可以透過更改sourcetype來完成

1
imagePicker.sourceType = .photoLibrary

使用資源

  • 先找路徑再找URL
1
2
let path = Bundle.main.path(forResource: "Right", ofType:"mp3")
let audioURL = URL(fileURLWithPath: path)
  • 直接找URL
1
let path = Bundle.main.url(forResource: "HipHop", withExtension: "mp4")

存資料(物件)

使用UserDefaults.standard.set和UserDefaults.standard.synchronize

  1. 用set並給一個key
  2. synchronize
1
2
3
var toDo = ["Buy milk", "iOS exam", "Sleep", "Make money"]
UserDefaults.standard.set(toDo, forKey:"todo")
UserDefaults.standard.synchronize()

取值,要記得取出來是anyObject,必須轉型,而且可能為nil(key不存在)。

1
2
3
4
5
guard let loaded = UserDefaults.standard.object(forKey: "toDo") as? [String] else{
  print("No such key")
  return
}
print(loaded)

如果存的是預設型別(像是Int),取值方法可以不用轉型

1
2
3
4
5
guard let loaded = UserDefaults.standard.integer(forKey: "toDo") else{
  print("No such key")
  return
}
print(loaded)

Property List (Plist)

Info.plist就是一種Property List的檔案。
plist可以很方便地幫你用Array或dictionary的形式存取資訊(String, Int …),個人覺得跟json沒兩樣。
使用的步驟如下

  1. 新增一個Property List檔案
  2. 在上面加上一些資訊(假設是一串Array)
  3. 使用Bundle.main.path拿到資源(檔案型態是plist)
  4. 利用NSArray將檔案轉成Array,或是NSDictionary檔案轉成dict
1
2
3
4
5
6
guard let scorePlist = Bundle.main.path(forResource: "Score", ofType: "plist"),
  let scoreArray = NSArray(contentsOfFile: scorePlist) else{
    print("Get Plist Error")
    return
}
print(scoreArray)

Activity Indicator

  • 用StoryBoard直接拉
  • 記得把Hides when stop打勾,不然圖案一直都在
  • startAnimating()開始轉
  • stopAnimationg()停止轉

COCOAPODS

先安裝 https://cocoapods.org/

在Xcode專案底下

1
pod init

編輯生出來podfile
加入需要的pod 專案

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'HelloCoCoaPods' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for HelloCoCoaPods
  pod 'Firebase/Database'

end

安裝專案

1
pod install

Reachability 測試有無連網

  1. 下載reachability
  2. 將Reachablility.h 及.m一起拖到專案,選擇新增Bridge
  3. Bridege中寫入#import "Reachability.h"
  4. 初始化Reachability(hostName: "www.apple.com")
    • 必須指定一個可連線的網址
  5. 使用方法startNotifier
  6. addObserver
  7. 接收notification

XML

解析XML XML delegate

值得用的APP

figure

登入與非登入狀態用不同的Controller

在Appdelegate裡面

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  if check != 1 {
  	let controller = UIStoryboard(name: "LogIn", bundle: nil).instantiateViewController(withIdentifier: "logIn")
  	self.window?.rootViewController = controller
  } else {
  	let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "tab")
  	self.window?.rootViewController = controller
  }
	return true
}

keyboard

彈出來時畫面自動向上

http://stackoverflow.com/questions/25693130/move-textfield-when-keyboard-appears-swift

點旁邊畫面自動縮回去

http://stackoverflow.com/questions/24126678/close-ios-keyboard-by-touching-anywhere-using-swift