Swiftで作れる簡単メモ帳アプリ

こんにちは、iOS、WebエンジニアのSHOです。
今回は簡単な機能だけで初心者でも作れるメモ帳アプリを作っていきたいと思います。

完成図としては⬇️こんな感じ

<img width="200" alt="スクリーンショット 2019-06-16 15.35.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/eab95522-55e5-262b-92e5-d5b2a4909d3a.png"><img width="200" alt="スクリーンショット 2019-06-16 15.41.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/072818bc-d173-5ebb-01be-9cac91ffea11.png"><img width="200" alt="スクリーンショット 2019-06-16 15.40.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/82946327-1eff-14c6-f8c0-03723bd0ab0d.png"><img width="200" alt="スクリーンショット 2019-06-16 15.40.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/998641a4-c77b-ca29-6cbf-e5669cd77946.png">

よくあるメモ帳ですね。

では早速MainStoryBoardを作っていくのですが、そちらは以下のように設計してください。
<img width="838" alt="スクリーンショット 2019-06-07 14.38.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/9b876643-84a8-86f3-b72a-1faae9a80d90.png">

##プログラム
###メモを保存する画面(AddMemoViewController)
<img width="129" alt="スクリーンショット 2019-06-17 16.51.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/0f382d4f-4cac-a9de-2d6f-0bf30de506e8.png">
コードは以下になります。

```
import UIKit

class AddMemoViewController: UIViewController {

    @IBOutlet weak var memoTextView: UITextView!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func save(_ sender: Any) {
        
        let inputText = memoTextView.text
        let ud = UserDefaults.standard
        if ud.array(forKey: "memoArray") != nil{
            //saveMemoArrayに取得
            var saveMemoArray = ud.array(forKey: "memoArray") as! [String]
                //テキストに何か書かれているか？
            if inputText != ""{
                //配列に追加
                saveMemoArray.append(inputText!)
                ud.set(saveMemoArray, forKey: "memoArray")
            }else{
                showAlert(title: "何も入力されていません")
                
            }
            
        }else{
            //最初、何も書かれていない場合
            var newMemoArray = [String]()
            //nilを強制アンラップはエラーが出るから
            if inputText != ""{
                //inputtextはoptional型だから強制アンラップ
                newMemoArray.append(inputText!)
                ud.set(newMemoArray, forKey: "memoArray")
            }else{
                showAlert(title: "何も入力されていません")
            }
        }
        showAlert(title: "保存完了")
        ud.synchronize()
    }
    
    func showAlert(title:String){
        let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert)
        
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        
        alert.addAction(UIAlertAction(title: "キャンセル", style: .cancel, handler: nil))
        
        self.present(alert, animated: true, completion:nil)   
    }
}

```

###保存されたリストを確認する画面(ViewController)
<img width="126" alt="スクリーンショット 2019-06-17 16.55.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/019eea47-4890-b121-0d82-ea79b0b03968.png">

```
import UIKit

class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
    @IBOutlet weak var memoTableView: UITableView!
    var memoArray = [String]()
    
    let ud = UserDefaults.standard
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return memoArray.count
    }
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "memoCell", for: indexPath)
        cell.textLabel?.text = memoArray[indexPath.row]
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.performSegue(withIdentifier: "toDetail", sender: nil)
        //押したら押した状態を解除
        tableView.deselectRow(at: indexPath, animated: true)
    }
    

    override func viewDidLoad() {
        super.viewDidLoad()
        
        memoTableView.delegate = self
        memoTableView.dataSource = self
    }
    override func viewWillAppear(_ animated: Bool) {
        loadMemo()
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        //destinationのクラッシュ防ぐ
        if segue.identifier == "toDetail"{
            //detailViewControllerを取得
            //as! DetailViewControllerでダウンキャストしている
            let detailViewController = segue.destination as! DetailViewController
            //遷移前に選ばれているCellが取得できる
            let selectedIndexPath = memoTableView.indexPathForSelectedRow!
            detailViewController.selectedMemo = memoArray[selectedIndexPath.row]
            detailViewController.selectedRow = selectedIndexPath.row
        }
    }
    func loadMemo(){
        if ud.array(forKey: "memoArray") != nil{
            //取得 またas!でアンラップしているのでnilじゃない時のみ
            memoArray = ud.array(forKey: "memoArray") as![String]
            //reloadしてくれる
            memoTableView.reloadData()
        }
    }
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        
        if editingStyle == .delete {
            
            //resultArray内のindexPathのrow番目をremove（消去）する
            memoArray.remove(at: indexPath.row)
            
            //再び
アプリ内に消去した配列を保存
            ud.set(memoArray, forKey: "memoArray")
            
            //tableViewを更新
            tableView.reloadData()
        }
    }
}
```

###詳細を表示する画面(DetailViewController)

<img width="161" alt="スクリーンショット 2019-06-17 16.58.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/7cb37109-aff8-49e7-d54b-3a80a90d34c9.png">

```
import UIKit

class DetailViewController: UIViewController {
    @IBOutlet weak var memoTextView: UITextView!
    
    var selectedRow:Int!
    var selectedMemo : String!
    
    override func viewDidLoad() {
        super.viewDidLoad()

       memoTextView.text = selectedMemo
    }
    
    @IBAction func deleteMemo(_ sender: Any) {
        let ud = UserDefaults.standard
        if ud.array(forKey: "memoArray") != nil{
            var saveMemoArray = ud.array(forKey: "memoArray") as![String]
            saveMemoArray.remove(at: selectedRow)
            ud.set(saveMemoArray, forKey: "memoArray" )
            ud.synchronize()
            //画面遷移
            
            self.navigationController?.popViewController(animated: true)
        }
    }
}
```

これで以上になります。
サンプルコードは
https://github.com/matushinn/DetailMemo