寒川アクアブログ

美容師しながらアプリ開発していて水草が趣味の私のブログです

【Swift4】ToDoリストアプリを作る。

f:id:kentaro198477:20190207011347j:plain

こんな感じのTODOリストを作ってみます。
ポイントは
・コアデータを利用してタスク情報を永続化
・テーブルビューをContainerViewに埋め込む形で利用
です。

何回かに分けてご紹介します。コードについては、拙い部分や、もっとこうした方がスッキリするよ!といったところがあるかもしれません。その際は教えていただけると助かります。
UIの作成に際してのオートレイアウトの使い方については割愛します。

プロジェクト作成

新規プロジェクト作成の際に
Use Core Data
にチェックを入れます(デフォルトでチェック入っている)。
これでCoreDataを簡単に利用できるようになります。

TableViewControllerをContainerViewに埋め込む


ストーリーボード上で、メインのViewController(以下ViewController)にContainerViewを画面いっぱいに配置します。
自動的に作られるViewControllerを選択して、deleteを押して削除します(ストーリーボード上から消え去ります)。
ストーリーボード上にTableViewControllerを配置。
ContainerViewから、controlキーを押しながらTableViewControllerまでドラッグし、ポップアップからEmbedをクリックします。

f:id:kentaro198477:20190207011305p:plain
ContainerViewにTableViewControllerを含めることができました。

TableViewではなくTableViewControllerを使うのは、大きな利点があります。それは、セルに後ほどTextViewを配置しますが、これのテキストを編集しようとタップすると、TextViewがキーボードに隠れてしまうことがあります。TableViewControllerであれば、TextViewが隠れないように自動的にスクロールしてくれます。

TableViewControllerのセルのデザイン

ToDoリストっぽい、チェックボックスとテキストのデザインを作ります。
SwiftにはチェックボックスのUI部品がないので、まずはこれを作ります。
チェックボックス用のチェック済み、未チェックの画像を用意し、Assetsフォルダに投げ込みます。
名前はそれぞれ、checkedとuncheckedにしました。

New File…から、Cocoa Touch Classを選び、UIButtonを継承したCheckBoxというファイルを作ります。

import UIKit

class CheckBox: UIButton {

    // Images
    let checkedImage = UIImage(named: "checked")! as UIImage
    let uncheckedImage = UIImage(named: "unchecked")! as UIImage
    
    // Bool property
    var isChecked: Bool = false {
        didSet{
            if isChecked == true {
                self.setImage(checkedImage, for: UIControl.State.normal)
            } else {
                self.setImage(uncheckedImage, for: UIControl.State.normal)
            }
        }
    }
    
    override func awakeFromNib() {
        self.addTarget(self, action:#selector(buttonClicked(sender:)), for: UIControl.Event.touchUpInside)
        self.isChecked = false
    }
    
    @objc func buttonClicked(sender: UIButton) {

    }
    
    func setChecked(_ check : Bool){
        isChecked = check
    }
}

ボタンを押した時にチェックマークを反転させるようにはしません。

PrototypeCellsにCheckBoxと、TextViewを配置する

CheckBoxを置くには、UIButtonを配置してから、クラスをCheckBoxに変更します。
ここら辺は、自由にレイアウトしてください!

テーブルビュー情報

UITableViewControllerを継承した、TableViewControllerというファイルを作ります。
ストーリーボード上のUITableViewControllerのクラスをTableViewControllerに変更します。
ViewControllerから、TableViewControllerのメソッドを呼べるように、TableViewControllerの参照を保持しておきます。

import UIKit

class ViewController: UIViewController {

    var tableViewController:TableViewController!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let tableViewController = segue.destination as? TableViewController {
             self.tableViewController = tableViewController
        }
    }
}

カスタムセルを定義する

UITableViewCellを継承したTableViewCellというファイルを作ります。
ストーリーボード上のPrototype CellのクラスをTableViewCellにし、Identifierを「Cell」にします。
TableViewCellに先ほど配置したチェックボックスとテキストビューを、アウトレット接続します。

@IBOutlet weak var checkBox: CheckBox!
@IBOutlet weak var textView: UITextView!

TableViewControllerに戻り、以下を追加します。

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
  
        // Configure the cell...

        return cell
    }

withIdentifier: “Cell”にし、as! TableViewCellを付け加えています。

一息ついて、ひとまず動作確認

    override func numberOfSections(in tableView: UITableView) -> Int {
               return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //    後で直してください
        return 1
    }

    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
        
        cell.textView.text = “適当に長い文章を入れてみます”

        // Configure the cell...

        return cell
    }

正しく表示されましたか?
TextViewで長文を表示する際にスクロールさせないようにするには、プロパティのScrolling Enabledのチェックを外します。スクロールバーが非表示になり、全ての文章が表示されるようになります。