6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swift4,Xcode10対応:プログラミング初心者でも簡単に作れるRealmとFSCalendarを用いた日記アプリ作成(2)

Last updated at Posted at 2019-02-10

#プログラミング初心者でも簡単に作れるRealmとFSCalendarを用いた日記アプリ作成(2)

-環境-
・Xcode10
・Swift4

前回はパーツの配置まで行いました。
プログラミング初心者でも簡単に作れるRealmとFSCalendarを用いた日記アプリ作成(1)

今回は、コードを書いていきます。

##3-3 コードを書く
ここからコードを書いていきます。
最初は写経で大丈夫です。

###3-3-0 コードを書くためのファイルを作成する。
ファイルの作成の仕方は以下の手順です。

既にファイルがある場所(Xcodeの左側)で右クリック
→「New File」を選択
→「Cocoa Touch Class」を選択

以上の手順をすると以下の画像が出るはずです。

スクリーンショット 2019-02-10 21.41.05.png

ここで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 日記のモデルのコードを書く。

Diary.swift
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のコードを書く。

CalendarViewController.swift

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() {
        //dataSourcedelegateメソッドが使えるように。
        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のコードを書く。

AddDiaryViewController.swift
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のコードを書く。

DetailDiaryViewController.swift

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にコードを書く

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

スクリーンショット 2019-02-10 21.52.19.png

###3-4-2 パーツを関連付け

それぞれのパーツを以下の画像の要領で関連付けしましょう。

スクリーンショット 2019-02-10 21.58.02.png

関連付けするパーツは以下の通りです。

①カレンダーを閲覧する画面
outlets: calendar, diaryTitleTableView

②追加画面
outlets: titleTexitField, detailTextView
actions: save

③詳細画面
outlets: detailTextView

##4 デバッグする

ここまでできれば、あとは動くかどうかチェックしてみましょう!
動かない場合は見返してみましょう。

プログラミング初心者でも簡単に作れるRealmとFSCalendarを用いた日記アプリ作成(1)

##GithubURL

今回のアプリを以下のリンクからダウンロードできます。
https://github.com/atsutko/Diary

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?