セグエ

はじめに

segueの理解したとこアウトプット

実行環境

  • swift : 4.2.1
  • xcode : 10.1

コード

class TimeView : UIViewController {

    var set_hour: Int = 1
    var set_min: Int = 2
    var set_sec: Int = 3

    override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
        }

    override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }

    // 値渡し
    @IBAction func startSegue(_ sender: Any) {
        performSegue(withIdentifier: "NextView", sender: nil)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let next = segue.destination as? NextView
        let _ = next?.view
        next?.count_hour = self.set_hour
        next?.count_min = self.set_min
        next?.count_sec = self.set_sec
    }
}

アウトプット

  • storyboardで遷移先にcontrol接続()
  • storyboardで繋いだ矢印をクリックしてwithIdentifierの名前を遷移先のクラス名にする(ここではNextView)
  • 遷移前のクラスで上のコードを記述
  • func prepareの最初2行の記述で、遷移先の変数にアクセスできる(next?.遷移先の変数)
  • そいつに遷移前の値を代入すればok。向こうで取り出せる

課題

  • オートレイアウト

UIPickerView

はじめに

徐々にアプリっぽくなってきた

実行環境

  • swift : 4.2.1
  • Xcode : 10.1

ソースコード

import UIKit

class SetTime: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    
    // 選択肢
    let dataListSec  = Array(0...59)
    let dataListMin  = Array(0...59)
    let dataListHour = Array(0...8)
    
    @IBOutlet weak var picker: UIPickerView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // プロトコル
        // storyboardからcontrolでViewの黄色いとこに接続すれば下の二つは記述しなくてもおkっぽい
        //picker.delegate = self
        //picker.dataSource = self
        
        // 表示する項目を指定
        self.picker.selectRow(1, inComponent: 0, animated: true) // hour
        self.picker.selectRow(0, inComponent: 1, animated: true) // min
        self.picker.selectRow(0, inComponent: 2, animated: true) // sec

    }
    
    
    // UIPickerViewDataSource
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        // 表示する列数
        return 3
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        // アイテム表示個数を返す
        
        if component == 0 {
            return dataListHour.count
        }
        if component == 1 {
            return dataListMin.count
        }
        else {
            return dataListSec.count
        }
    }
    
    
    // UIPickerViewDelegate
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        // 表示する文字列を返す
        
        if component == 0 {
            return String(dataListHour[row])
        }
        if component == 1 {
            return String(dataListMin[row])
        }
        else {
            return String(dataListSec[row])
        }
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        // 選択時の処理
        
        if component == 0 {
            // hour
            print(dataListHour[row])
        }
        if component == 1 {
            // min
            print(dataListMin[row])
        }
        else {
            // sec
            print(dataListSec[row])
        }
    }
}

storyboard

  • UIPickerとUILabelを配置
  • UIPickerはcontrol接続でstoryboardの上の黄色い丸のとこにやると、delegate, datasourceの記述を省けた。
  • UIPicker Outlet接続

commandクリックで記述すべきメソッドを確認

選択時の処理

  • func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
    ここで選択した時間を取得して、セグエで値渡しできそう。んで遷移後カウントダウン。

課題

  • AutoLayout問題

思ったこと

コマンドクリック便利

参考文献

[Swift3] リストから項目を選択するUIPickerViewの使い方 - JoyPlotドキュメント

selectorとsender

はじめに

タイマーを作りたいんじゃ
Timer.scheduledTimer() の使い方についてメモ

ソース

import UIKit
//import Foundation

class TimeView : UIViewController {
    
    var timer = Timer()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.timer = Timer.scheduledTimer(timeInterval: 5.0,
                                          target:   self,
                                          selector: #selector(TimeView.debug),
                                          userInfo: nil,
                                          repeats:  true)
    }
    @objc func debug() -> Void {
        print("5秒経過")
    }
}

scheduledTimer()

timeInterval selectorで設定したメソッドを実行するまでの時間
target 実行するクラス
selector 実行するメソッド
usrInfo メソッドに渡す
repeats trueは繰り返し、falseは一度だけ

selector: #selector(TimeView.debug))

  • 引数があるときは、#selector(TimerView.debug(_:)ってする

@objc func debug() -> Void {}

  • @objc記述しないとダメ
  • 引数があるときは _ sender:Timerで受け取る
  • senderは調べても分からんかった

最後に

今日全然進まんかった

UITableView : cellの追加(セルの名前設定も)と削除

はじめに

cellの追加と削除についてアウトプット
自分用.memo
このブログ横幅狭い

実行環境

  • swift 4.0 (多分)
  • Xcode : 10.1

注意

qiita.com

qiita.com からの引用です

ソースコード全体

ソースコード

import UIKit

class ListViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    @IBOutlet weak var tableView: UITableView!
    
    // 項目
    var data = [String]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        // テーブルビューのdataSourceとdelegateを設定
        tableView.dataSource = self
        tableView.delegate = self
    }
  
    //セルの編集許可
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
    {
        return true
    }
    
    //スワイプしたセルを削除
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == UITableViewCell.EditingStyle.delete {
            data.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath as IndexPath], with: UITableView.RowAnimation.automatic)
        }
    }
    
    // cellの追加
    @IBAction func tapAdd(_ sender: UIBarButtonItem) {
        let alert: UIAlertController = UIAlertController(title: "セルの追加",
                                                         message: "追加する項目を入力してください",
                                                         preferredStyle: UIAlertController.Style.alert)
        alert.addTextField(configurationHandler: nil)
        let okAction = UIAlertAction(title: "OK",
                                     style: UIAlertAction.Style.default,
                                     handler:{
                                        (action: UIAlertAction) -> Void in
                                        self.data.insert(alert.textFields!.first!.text!, at: 0)
                                        // <重要>
                                        self.tableView.beginUpdates()
                                        self.tableView.insertRows(at: [IndexPath(row: 0, section: 0)],
                                                                  with: .automatic)
                                        self.tableView.endUpdates()
        })
        let cancelAction = UIAlertAction(title: "キャンセル",
                                         style: UIAlertAction.Style.cancel,
                                         handler: nil)
        alert.addAction(okAction)
        alert.addAction(cancelAction)
        self.present(alert, animated: true, completion: nil)
    }

    // 生成するセルの数
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
       
        return self.data.count
    }
    
    // セルの内容を知らせるメソッド
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = self.data[indexPath.row]
        
        return cell
    }
    
    // メモリ警告
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

アウトプット

セルの編集許可

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
    {
        return true
    }

セルの削除にはこれが必要

スワイプしたセルを削除

   func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == UITableViewCell.EditingStyle.delete {
            data.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath as IndexPath], with: UITableView.RowAnimation.automatic)
        }
    }

スワイプされたらこの関数が呼ばれる

ifの所のEditingStyleは列挙体。commandクリックで中身が

  • none
  • delete
  • insert

であることが分かる。
スワイプされた時に引数でeditingStyleを受け取り、deleteなら以下を実行

data.remove(at: indexPath.row) で配列の中身を削除した後
tableView.delete() でセルを削除する。

  • asはアップキャスト
  • with:はアニメーションの方式を指定
  • RowAnimationは列挙体でcommandクリックで

RowAnimation

 public enum RowAnimation : Int {

        
        case fade

        case right // slide in from right (or out to right)

        case left

        case top

        case bottom

        case none // available in iOS 3.0

        case middle // available in iOS 3.2.  attempts to keep cell centered in the space it will/did occupy

        case automatic // available in iOS 5.0.  chooses an appropriate animation style for you
    } 

と分かる。

cellの追加

// cellの追加
    @IBAction func tapAdd(_ sender: UIBarButtonItem) {
        let alert: UIAlertController = UIAlertController(title: "セルを追加",
                                                         message: "追加する項目を入力してください",
                                                         preferredStyle: UIAlertController.Style.alert)
        alert.addTextField(configurationHandler: nil)
        let okAction = UIAlertAction(title: "OK",
                                     style: UIAlertAction.Style.default,
                                     handler:{
                                        (action: UIAlertAction) -> Void in
                                        self.data.insert(alert.textFields!.first!.text!, at: 0)
                                        // <重要>
                                        self.tableView.beginUpdates()
                                        self.tableView.insertRows(at: [IndexPath(row: 0, section: 0)],
                                                                  with: .automatic)
                                        self.tableView.endUpdates()
        })
        let cancelAction = UIAlertAction(title: "キャンセル",
                                         style: UIAlertAction.Style.cancel,
                                         handler: nil)
        alert.addAction(okAction)
        alert.addAction(cancelAction)
        self.present(alert, animated: true, completion: nil)
    }

(ライブラリでItemをtableViewに置いてoutlet接続後(tapAdd)の話)

  • UIAlertController.Style.alertiPhoneの充電が20%になった時に出てくるあれ。

  • UIAlertController.Style.actionSheetは下の方に出てくるやつ。

  • alert.addTextField(configurationHandler: nil) はテキスト入力ボックスの追加

UIAlertAction(title: "OK",
                        style: UIAlertAction.Style.default,
                        handler:{})

はOKボタンの設置&OKを押した時のアクションをhandler以下に記述(クロージャ)。

UIAlertAction.Style

extension UIAlertAction {

    
    @available(iOS 8.0, *)
    public enum Style : Int {

        
        case `default` // titleが青文字

        case cancel     // cancelの時に使う

        case destructive   // titleが赤文字
    }
}

  • 入力したテキストは
self.data.insert(alert.textFields!.first!.text!, at: 0)

で拾える。

  • insertRows() (セルの挿入)をするには、
    self.tableView.beginUpdates()
    self.tableView.endUpdates()
    で挟まないといけない。
self.tableView.beginUpdates()
self.tableView.insertRows(at: [IndexPath(row: 0, section: 0)],with: .automatic)
self.tableView.endUpdates()
  • キャンセル時は何もしないので handler:nil
let cancelAction = UIAlertAction(title: "キャンセル",
                                         style: UIAlertAction.Style.cancel,
                                         handler: nil)
  • UIAlertに表示する。
alert.addAction(okAction)
alert.addAction(cancelAction)
  • モーダルビュー登場。
self.present(alert, animated: true, completion: nil)



アウトプット終わり!(疲れた)

参考

qiita.com

qiita.com