#プログラミング初心者でも簡単に作れるRealmとFSCalendarを用いた日記アプリ作成(2)
-環境-
・Xcode10
・Swift4
前回はパーツの配置まで行いました。
プログラミング初心者でも簡単に作れるRealmとFSCalendarを用いた日記アプリ作成(1)
今回は、コードを書いていきます。
##3-3 コードを書く
ここからコードを書いていきます。
最初は写経で大丈夫です。
###3-3-0 コードを書くためのファイルを作成する。
ファイルの作成の仕方は以下の手順です。
既にファイルがある場所(Xcodeの左側)で右クリック
→「New File」を選択
→「Cocoa Touch Class」を選択
以上の手順をすると以下の画像が出るはずです。
ここでClassとSubClassを指定します。
初めは
Class:CalendarViewController
SubClass:UIViewController
とします。
これがCalendarを表示する画面を制御するファイルです。
上記の手順で以下のファイルも作ってください。
②日記のモデル
Class:Diary
SubClass:NSObject
③追加画面を制御するファイル
Class: AddDiaryViewController
SubClass:UIViewController
④詳細画面を制御するファイル
Class:DetailDairyViewController
SubClass:UIViewController
⑤アラート表示のためのファイル
Class: SimpleAlert
SubClass: NSObject
###3-3-1 日記のモデルのコードを書く。
import UIKit
import Realm
import RealmSwift
class Diary: Object {
static let realm = try! Realm()
//Diaryのプロパティを定義
@objc dynamic private var id = 0
@objc dynamic var date: String = ""
@objc dynamic var title: String = ""
@objc dynamic var note: String = ""
//キーの設定
override static func primaryKey() -> String? {
return "id"
}
//新規作成
static func create() -> Diary {
let diary = Diary()
diary.id = lastId()
return diary
}
//日付指定で読み込み
static func search(date: Date) -> [Diary] {
let selectedDay = Diary.changeDateType(date: date)
let config = Realm.Configuration(schemaVersion: 1, migrationBlock: { migration, oldSchemaVersion in
if (oldSchemaVersion < 1) {
}
})
Realm.Configuration.defaultConfiguration = config
if realm.objects(Diary.self).filter("date == '\(selectedDay)'").isEmpty == false {
let objects = realm.objects(Diary.self).filter("date == '\(selectedDay)'")
var diaryArray: [Diary] = []
for object in objects {
diaryArray.append(object)
}
return diaryArray
} else {
return []
}
}
//Idの設定
static func lastId() -> Int {
if let object = realm.objects(Diary.self).last {
return object.id + 1
} else {
return 1
}
}
//保存
func save() {
try! Diary.realm.write {
Diary.realm.add(self)
}
}
//日付のフォーマット指定
static func changeDateType(date: Date) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM月dd日"
let text = dateFormatter.string(from: date)
return text
}
}
###3-3-2 CalendarViewControllerのコードを書く。
import UIKit
import FSCalendar
import Realm
import RealmSwift
class CalendarViewController: UIViewController {
var diaryArray: [Diary] = []
@IBOutlet weak var calendar: FSCalendar!
@IBOutlet weak var diaryTitleTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
calendar.delegate = self
calendar.dataSource = self
configureTableView()
diaryArray = Diary.search(date: Date())
}
override func viewWillAppear(_ animated: Bool) {
diaryArray = Diary.search(date: Date())
diaryTitleTableView.reloadData()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toDetail" {
let detailDiaryViewController = segue.destination as! DetailDairyViewController
let selectedIndex = diaryTitleTableView.indexPathForSelectedRow!
detailDiaryViewController.selectedDiary = diaryArray[selectedIndex.row]
}
}
// Private
func configureTableView() {
//dataSourceとdelegateメソッドが使えるように。
diaryTitleTableView.delegate = self
diaryTitleTableView.dataSource = self
//セルの高さを30.0で固定
diaryTitleTableView.rowHeight = 30.0
//余白を消す
diaryTitleTableView.tableFooterView = UIView()
}
}
extension CalendarViewController: UITableViewDelegate, UITableViewDataSource {
// MARK: - TableView DataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return diaryArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "diaryCell")!
cell.textLabel?.text = diaryArray[indexPath.row].title
return cell
}
// MARK: - TableView Delegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// 詳細画面に遷移
self.performSegue(withIdentifier: "toDetail", sender: nil)
}
}
extension CalendarViewController: FSCalendarDataSource, FSCalendarDelegate {
// MARK: - FSCalendar Delegate
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
//日付選択時に呼ばれるメソッド
diaryArray = Diary.search(date: date)
diaryTitleTableView.reloadData()
}
}
###3-3-3 AddDiaryViewControllerのコードを書く。
import UIKit
class AddDiaryViewController: UIViewController, UITextFieldDelegate, UITextViewDelegate {
@IBOutlet weak var titleTexitField: UITextField!
@IBOutlet weak var detailTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
titleTexitField.delegate = self
detailTextView.delegate = self
}
// MARK: - TextField Delegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
// MARK: - TextView Delegate
func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
textView.resignFirstResponder()
return true
}
@IBAction func save() {
if titleTexitField.text != "" {
if detailTextView.text != "" {
let newDiary = Diary.create()
newDiary.title = titleTexitField.text!
newDiary.note = detailTextView.text
let today = Diary.changeDateType(date: Date())
newDiary.date = today
newDiary.save()
self.navigationController?.popViewController(animated: true)
} else {
SimpleAlert.showAlert(viewController: self, title: "日記なし", message: "内容を描いてください", buttonTitle: "OK")
}
} else {
SimpleAlert.showAlert(viewController: self, title: "タイトルなし", message: "タイトルを書いてください", buttonTitle: "OK")
}
}
}
###3-3-4 DetailDiaryViewControllerのコードを書く。
import UIKit
class DetailDairyViewController: UIViewController {
var selectedDiary = Diary()
@IBOutlet weak var detailTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.title = "\(selectedDiary.title)"
detailTextView.text = selectedDiary.note
}
}
###3-3-5 SimpleAlert.swiftにコードを書く
import UIKit
struct SimpleAlert {
static func showAlert(viewController: UIViewController, title: String, message: String, buttonTitle: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: buttonTitle, style: .default) { (action) in
alert.dismiss(animated: true, completion: nil)
}
alert.addAction(okAction)
viewController.present(alert, animated: true, completion: nil)
}
}
##3-4 関連付け
###3-4-1 コードと画面を繋ぐ
以下の画像を見ながら、それぞれの画面のClassを指定しましょう。
①カレンダーを閲覧する画面
Class: CalendarViewController
②追加画面
Class: AddDiaryViewController
③詳細画面
Class:DetailDairyViewController
###3-4-2 パーツを関連付け
それぞれのパーツを以下の画像の要領で関連付けしましょう。
関連付けするパーツは以下の通りです。
①カレンダーを閲覧する画面
outlets: calendar, diaryTitleTableView
②追加画面
outlets: titleTexitField, detailTextView
actions: save
③詳細画面
outlets: detailTextView
##4 デバッグする
ここまでできれば、あとは動くかどうかチェックしてみましょう!
動かない場合は見返してみましょう。
プログラミング初心者でも簡単に作れるRealmとFSCalendarを用いた日記アプリ作成(1)
##GithubURL
今回のアプリを以下のリンクからダウンロードできます。
https://github.com/atsutko/Diary