アプリ開発の最難関。カレンダー。
もう定番と言ってもいいのではないでしょうか。
アプリ開発の最難関、カレンダーをつかったアプリをこの回で作っていきましょう。
目次
環境
- Xcode 8.2.1
- Swift 3.0
- CocoaPods 1.1.1
前提として
CocoaPodsは導入済みのものとして話をすすめます。
まだCocoaPodsを導入していない方はこちらのページの手順1と2を行ってください。
プロジェクトの作成
Xcodeを起動して、新規プロジェクトを作成します。今回は「DiarySampler」としてプロジェクトを作成します。
CocoaPodsの導入
今回は、JBDatePickerをつかいます。
READMEを見ながらできるひとはそのまま進めてください。
Terminalを開き、DiarySampler.xcodeproj
のある階層までコマンドを進めます。
pod init
をしてPodfile
がその階層にあることを確認して、Sublime TextなどのテキストエディタでPodfileを開きましょう。上級者はvimでも構いません。
# 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
を保存します。
その後、ターミナルを開き、
pod install
を実行します。
pod installできないとき
Unable to find a specification for 'JBDatePicker'と表示され、ごくまれにインストールできないときがあるようです。
こちらの記事を参照したところ、つぎの2つのコマンドでCocoapodsが初期化されるようです。
【iOS Swift入門 #230】[!] Unable to find a specification for GoogleMaps
でインストールできない
sudo rm -fr ~/.cocoapods/repos/master
pod setup
プロジェクトファイルを起動
先ほど開いていたXcodeは一度「Command+Q」ですべて閉じましょう。(Xcodeファイルが開いていると正常に起動しません。)
FinderでDiarySamplerのプロジェクトファイルにいき、DiarySampler.xcworkspace
を開きます。
※pod installを実行したあとは、かならず白いアイコンの「xcworkspace」 のほうを開きましょう。
正常に起動すると、以下のように通常のプロジェクトファイルのほかにPodsというディレクトリが存在し、中身を確認するとちゃんとJBDatePickerがはいっていることがわかります。
この地点で一度「Command+B」でビルド確認をして、エラーがないことを確認しましょう。
ViewControllerにViewを追加
それではいよいよライブラリを使ってカレンダーを表示していきましょう。
Main.storyboard
を開き、カレンダーを表示したいViewControllerに「View」部品を挿入します。
次に、Custom Classを開き、先ほど設置したViewのCustom Classを「JBDatePickerView」に設定します。Classの部分にJBDatePickerView
と入力してEnterキーを押すと、その下のModuleにJBDatePicker
と自動的に入力されます。
※Moduleは自動的に入力されるので、手動で入力しないでください!
手動で入力するとうまくビルドされない場合があります。
.swiftファイルに処理を書こう
いよいよViewController.swift
ファイルに処理を書いていきます。
READMEファイルをみれば書き方が書かれていますので、わかる方はそちらを進めてください。
まず、新しくモジュールを使うのでimport
します。import UIKit
の下に次の1文を書きます。
import JBDatePicker
次に、ストーリーボード上の部品を使うので、IBOutletで部品とコードを繋ぎます。
@IBOutlet var datePicker: JBDatePickerView!
今回は、JBDatePickerView
というクラスの部品に対しdatePicker
という名前をつけました。@IBOutlet
と書いたので、関連付けも忘れずに行っておきましょう!
そして、Delgateの設定です。
まず、Delegateを使うことを宣言しておきましょう。
class ViewController: UIViewController, JBDatePickerViewDelegate {
JBDatePickerViewDelegate
を使うことをまず最初に宣言します。これがあれば、このクラス内でDelegateが使えます。
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が存在していることを明示できました。
func didSelectDay(_ dayView: JBDatePickerDayView) {
print("date selected: \(dayView.date!)")
}
そして最後に、delegateメソッドであるdidSelectDay
メソッドを書きます。
これにより、didSelectDayしたとき(=日にちを選択したとき)にこのメソッドが呼ばれることになりました。今回は、コンソールに日時を出力できるようにしました。
おまじない
今回は、READMEで、viewDidLayoutSubviewsに処理を書いてね、と言われているので、書いておきます。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
datePicker.updateLayout()
}
完成!実行!
それでは一通り完成したので、ビルドして実行してみましょう!
日付の表示がおかしい
1日日付がずれてしまっています。タイムゾーンなどが関連しているようです。
@IBOutletでdatePickerの宣言をしたあとの行に、つぎのコードを追加します。
lazy var dateFormatter: DateFormatter = {
var formatter = DateFormatter()
formatter.timeStyle = .none
formatter.dateStyle = .medium
return formatter
}()
さらに、didSelectDayを次のように変更します。
func didSelectDay(_ dayView: JBDatePickerDayView) {
print("date selected: \(dateFormatter.string(from: dayView.date!))")
}
これで、一度DateFormatterをとおしてから表示することで日付のみ出すことができました。
コード全貌
//
// 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!))")
}
}