Swiftで日記アプリを作ろう 〜その1 カレンダー表示編〜

# アプリ開発の最難関。カレンダー。
もう定番と言ってもいいのではないでしょうか。
アプリ開発の最難関、カレンダーをつかったアプリをこの回で作っていきましょう。

# 目次
- [その1 カレンダー表示編](http://qiita.com/ryoegu/items/1e5d1b8cadbf0061f6a7)
- [その2 Realm導入編](http://qiita.com/ryoegu/items/1839d4eaecf74b49a745)
- [その3 Realm活用編](http://qiita.com/ryoegu/items/2249555be43dc7ed617a)


# 環境
- Xcode 8.2.1
- Swift 3.0
- CocoaPods 1.1.1

# 前提として
CocoaPodsは導入済みのものとして話をすすめます。
まだCocoaPodsを導入していない方は[こちらのページ](http://qiita.com/shishimo@github/items/d7f508e2489bcc68050e)の手順1と2を行ってください。

# プロジェクトの作成
![image](https://qiita-image-store.s3.amazonaws.com/0/44105/a21c948d-f047-b04a-760d-cf59e507aac8.png)

Xcodeを起動して、新規プロジェクトを作成します。今回は「DiarySampler」としてプロジェクトを作成します。

# CocoaPodsの導入
今回は、[JBDatePicker](https://github.com/Tuslareb/JBDatePicker)をつかいます。
READMEを見ながらできるひとはそのまま進めてください。

Terminalを開き、`DiarySampler.xcodeproj`のある階層までコマンドを進めます。

```ruby:Terminal
pod init
```

をして`Podfile`がその階層にあることを確認して、Sublime TextなどのテキストエディタでPodfileを開きましょう。上級者はvimでも構いません。

```ruby:Podfile
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

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

  # === この下の1行を追加 ===
  pod 'JBDatePicker'
  

  # Pods for DiarySampler

  target 'DiarySamplerTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'DiarySamplerUITests' do
    inherit! :search_paths
    # Pods for testing
  end

end
```

`use_franeworks!`の下の行に`pod 'JBDatePicker'`を追加し、この`Podfile`を保存します。

その後、ターミナルを開き、

```ruby:Terminal
pod install
```

を実行します。

## pod installできないとき
Unable to find a specification for 'JBDatePicker'と表示され、ごくまれにインストールできないときがあるようです。
こちらの記事を参照したところ、つぎの2つのコマンドでCocoapodsが初期化されるようです。
[【iOS Swift入門 #230】[!] Unable to find a specification for `GoogleMaps`でインストールできない](http://swift.swift-studying.com/entry/2015/07/11/215204)

```ruby:Terminal
sudo rm -fr ~/.cocoapods/repos/master
pod setup
```

# プロジェクトファイルを起動
先ほど開いていたXcodeは一度「Command+Q」ですべて閉じましょう。（Xcodeファイルが開いていると正常に起動しません。）

![xc.png](https://qiita-image-store.s3.amazonaws.com/0/44105/51eda264-5f6b-5dd0-b6d3-e8c2309f91ed.png)
FinderでDiarySamplerのプロジェクトファイルにいき、`DiarySampler.xcworkspace`を開きます。
※pod installを実行したあとは、かならず白いアイコンの「xcworkspace」　のほうを開きましょう。

正常に起動すると、以下のように通常のプロジェクトファイルのほかにPodsというディレクトリが存在し、中身を確認するとちゃんとJBDatePickerがはいっていることがわかります。
![image](https://qiita-image-store.s3.amazonaws.com/0/44105/c2358fd0-9b93-4d09-09c4-860a4d0d673d.png)

この地点で一度「Command+B」でビルド確認をして、エラーがないことを確認しましょう。

# ViewControllerにViewを追加
それではいよいよライブラリを使ってカレンダーを表示していきましょう。
`Main.storyboard`を開き、カレンダーを表示したいViewControllerに「View」部品を挿入します。
![image](https://qiita-image-store.s3.amazonaws.com/0/44105/ab60128f-2c8b-39ba-29a3-c2abfaf025f7.png)

次に、Custom Classを開き、先ほど設置したViewのCustom Classを「JBDatePickerView」に設定します。Classの部分に`JBDatePickerView`と入力してEnterキーを押すと、その下のModuleに`JBDatePicker`と自動的に入力されます。
![image](https://qiita-image-store.s3.amazonaws.com/0/44105/ed577ab9-28b1-a4f2-56fb-77884698551c.png)

※Moduleは自動的に入力されるので、手動で入力しないでください！
手動で入力するとうまくビルドされない場合があります。

# .swiftファイルに処理を書こう
いよいよ`ViewController.swift`ファイルに処理を書いていきます。
READMEファイルをみれば書き方が書かれていますので、わかる方はそちらを進めてください。

まず、新しくモジュールを使うので`import`します。`import UIKit`の下に次の1文を書きます。

```swift:ViewController.swift
import JBDatePicker
```

次に、ストーリーボード上の部品を使うので、IBOutletで部品とコードを繋ぎます。

```swift:ViewController.swift
@IBOutlet var datePicker: JBDatePickerView!
```

今回は、`JBDatePickerView`というクラスの部品に対し`datePicker`という名前をつけました。`@IBOutlet`と書いたので、関連付けも忘れずに行っておきましょう！
![image](https://qiita-image-store.s3.amazonaws.com/0/44105/e2fafec9-0cbb-1edd-e272-cecd21b46f09.png)

そして、Delgateの設定です。
まず、Delegateを使うことを宣言しておきましょう。

```swift:ViewController.swift
class ViewController: UIViewController, JBDatePickerViewDelegate {
```

`JBDatePickerViewDelegate`を使うことをまず最初に宣言します。これがあれば、このクラス内でDelegateが使えます。

```swift:ViewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        datePicker.delegate = self //この行を追加
        
    }
 
```
次に、`viewDidLoad()`でdelegateがself（このクラス自身）であることを宣言します。これで、このクラス内にこのdatePickerのdelegateが存在していることを明示できました。

```swift:ViewController.swift
    func didSelectDay(_ dayView: JBDatePickerDayView) {
        print("date selected: \(dayView.date!)")
        
    }
```
そして最後に、delegateメソッドである`didSelectDay`メソッドを書きます。
これにより、didSelectDayしたとき（＝日にちを選択したとき）にこのメソッドが呼ばれることになりました。今回は、コンソールに日時を出力できるようにしました。

# おまじない
今回は、READMEで、viewDidLayoutSubviewsに処理を書いてね、と言われているので、書いておきます。

```swift:ViewController.swift
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        datePicker.updateLayout()
    }
```

# 完成！実行！
それでは一通り完成したので、ビルドして実行してみましょう！

![image](https://qiita-image-store.s3.amazonaws.com/0/44105/6e6fdd5d-ba6f-cfd5-252e-53a90eb74d21.png)


# 日付の表示がおかしい
1日日付がずれてしまっています。タイムゾーンなどが関連しているようです。

@IBOutletでdatePickerの宣言をしたあとの行に、つぎのコードを追加します。

```swift:ViewController.swift
    lazy var dateFormatter: DateFormatter = {
        var formatter = DateFormatter()
        formatter.timeStyle = .none
        formatter.dateStyle = .medium
        return formatter
    }()
```

さらに、didSelectDayを次のように変更します。

```swift:ViewController.swift
    func didSelectDay(_ dayView: JBDatePickerDayView) {
        print("date selected: \(dateFormatter.string(from: dayView.date!))")
    }
```

これで、一度DateFormatterをとおしてから表示することで日付のみ出すことができました。

![image](https://qiita-image-store.s3.amazonaws.com/0/44105/c392bca1-9e18-bea6-3613-9adf296347c5.png)

# コード全貌
```swift:ViewController.swift
//
//  ViewController.swift
//  DiarySampler
//
//  Created by Ryo Eguchi on 2017/01/01.
//  Copyright © 2017年 Ryo Eguchi. All rights reserved.
//

import UIKit
import JBDatePicker

class ViewController: UIViewController, JBDatePickerViewDelegate {

    
    @IBOutlet var datePicker: JBDatePickerView!
    
    lazy var dateFormatter: DateFormatter = {
        var formatter = DateFormatter()
        formatter.timeStyle = .none
        formatter.dateStyle = .medium
        return formatter
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        datePicker.delegate = self
        
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        datePicker.updateLayout()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func didSelectDay(_ dayView: JBDatePickerDayView) {
        print("date selected: \(dateFormatter.string(from: dayView.date!))")
    }


}

```

# その2へ続く
[その2 Realm導入編](http://qiita.com/ryoegu/items/1839d4eaecf74b49a745)