見出し画像

【徒然iOS】気ままにUIKit〜今週のコラム ローマは1日にしてならず〜

概要

2022/8/23に、当時やってたGAS(google apps script)の案件で退職が決まったのがきっかけでSwiftUIの日本語版の本

を皮切りに、2022年の5月に1回回してた

を12/6までで
「ひとつのアプリにまとめ終わったので、久しぶりにUIKitもやっとくかあ」
って軽いノリで始めた

も年末年始とか土日祝日はしっかりPCから離れながらでも、既に30本くらいの記事になったねえ〜〜〜。

実際に作りながら読んでくれてる人は、既に、

  • アウトレット接続とアクション接続の違い

  • デリゲート

  • stubsと赤と黄色のエラーへの対処方法

  • AutoLayout

  • JumptoDefinitionの使いどころ

くらいは、感覚的に身につけてくれてたら幸い。

多分、エラー対処の方法とかJumptoDefinitionの勘どころなんかを参考に、

こんなにあっさり対処できるんだ

って思ってくれた人もいるんじゃないかな、、、💦

まだまだ、

  • ImageView

  • CollectionView

  • ScrollView

  • TabView

  • TapGesture

  • MapKit

  • Navigation

  • Audio

  • CoreData

などの

よりアプリらしくする機能

が控えているんだけど、それもまた、

ゆっくり気ままに、数ヶ月かけて
週に3〜5個ずつくらい記事にしていけたらなあ

と思ってるところ💦
(*SpriteKitてゲームなんかも作れるフレームワークもあるんだけど、ゲームはUnityとか他のプラットフォームの方が向いてるかなと思うので、このマガジンでは、他の記事が終わって気が向いたらやろうかなくらい💦)

ここ数ヶ月で、

専門学校とか大学の講師のスカウトもちらほら来るんだけど、Xcode自体がMacさえあれば無料で入手ができて、Swift自体がモダンで直感的に誰でも書けるコード設計だから、

社会人こそ教育機関へ高い教育費と授業料を払わなくても、無料で気が向いた時に学べる記事があったら、iOSアプリ開発の裾野が広がるかもなあ。

と思って、自分も学び直しがてらゆっくり気ままにやってる感じ。
リスキリングとかリカレントとかよく知らんけど、
言葉ばかりで、時代のニーズにあったサービス提供があんまり進んでないなあとも思ったので。

今ちょうど、

も3分の1くらいまで終わったんだけど、ちょうど@Stateや@Binding、@EnvironmentといったPropatyWrapperあたりをやっていて、ホント、

プログラミングのコードは、世界共通

てことを実感してるトコ。

日本は

世界的にみても、教育費が高すぎるって言われているし、自分の拙い経験だけど、このマガジンを読んで、学校に行かなくても、自分の好きなアプリを作れる人が増えてくれたら嬉しいし、それで、

💃プログラミングの社会的な裾野を広げることになったら幸い🕺

あと数年後には、

IT人材が、日本全体で数十万人規模で不足するって言われてるのに、

  • 政策を決定する側は、予算を付けようにも知識がない。

  • 開発現場側には、目先の作業に追われてて、育成する時間と余裕がない。

  • 他は安すぎると言われているのに、教育費だけは高すぎて、学び直したくても、社会的には敷居が高い。

だろうからね。

無料にゆっくり気ままに〜〜〜

あと3分の2くらい = おそらく2〜3ヶ月くらいで終わるかな
と思うので、

🙇🙇‍♀️🙇‍♂️暫しのお付き合いを来週以降もよろしくお願いします🙇🙇‍♀️🙇‍♂️

裏を返すと、

ひとつのプログラミング言語なら、

ゆっくりやっても、数ヶ月で(記事にしながらでも)学習できる

焦って、2週間くらいで「習得しました」みたいなことなんてしなくていい
👉いくら本を2週間くらいで丸暗記したところで、

  • ゼロから何も作れない

  • バグやクラッシュが多い

だったら結局、意味がないって話。
(ま、開発現場で過去にそういう人ばかりを見てきたんだけど。)

週に3個ずつとか1日1個ずつでしっかり習得していけば、3ヶ月くらいで大抵のモノは作れるようになってる✨

ローマは1日にしてならず
目先の機能の解決策ばかりを追うよりも、
標準的な機能の全体図をしっかり俯瞰してもらえたら幸い
どうせ
1日多くても1記事しか出さないので、
1個習得したら、先に進むよりも、仕様を見直してみてね〜〜〜

なので、皆さんも

💃今週も良い週末を🕺

まとめ(今週までのコード)

前回のコラムでも書いたけど、コピペして貼り付けただけでは動かないので、ご注意を〜〜〜!

ViewController側

import UIKit
import AVFoundation

class ButtonViewController: UIViewController{
    
    @IBOutlet weak var testLabel: UILabel!
    
    @IBAction func buttonTouchUpInside(_ sender: UIButton) {
        self.testLabel.text = "Touch Up Inside!"
    }
    @IBAction func buttonTouchDown(_ sender: UIButton) {
        self.testLabel.text = "Touch Down!"
    }
    @IBAction func buttonTouchDownRepeat(_ sender: UIButton) {
        self.testLabel.text = "Touch Down Repeat!"
    }
    @IBAction func buttonTouchDragEnter(_ sender: UIButton) {
        self.testLabel.text = "Touch Drag Enter!"
    }
    @IBAction func buttonTouchDragExit(_ sender: UIButton) {
        self.testLabel.text = "Touch Drag Exit!"
    }
    
    @IBAction func buttonTouchDragInside(_ sender: UIButton) {
        self.testLabel.text = "Touch Drag Inside!"
    }
    @IBAction func buttonTouchDragOutside(_ sender: UIButton) {
        self.testLabel.text = "Touch Drag Outside!"
    }
    
    @IBAction func buttonTouchUpOutsideTouchUpOutside(_ sender: UIButton) {
        self.testLabel.text = "Touch Up Outside!"
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

class TextFieldViewController: UIViewController,UITextFieldDelegate {
    
    @IBOutlet weak var labelTextField: UILabel!
    
    @IBOutlet weak var myTextFieldEditingChanged: UITextField!
    
    @IBAction func textFieldEditingChanged(_ sender: UITextField) {
        labelTextField.text = sender.text
    }
    
    @IBAction func textFieldDidEndOnExit(_ sender: UITextField) {
        labelTextField.text = sender.text
    }
    
    @IBOutlet weak var myTextFieldEditingDidEnd: UITextField!
    
    @IBAction func textFieldEditingDidEnd(_ sender: UITextField) {
        labelTextField.text = sender.text
    }
    
    @IBOutlet weak var myTextFieldEditingDidBegin: UITextField!
    
    @IBAction func textFieldEditingDidBegin(_ sender: UITextField) {
        labelTextField.text = sender.text
    }
    
    //今回追加
    @IBOutlet weak var testEventLabel: UILabel!
    @IBOutlet weak var testLabel2: UILabel!
    @IBOutlet weak var testLabel3: UILabel!
    @IBOutlet weak var testLabel4: UILabel!
    @IBOutlet weak var testLabel5: UILabel!
    @IBOutlet weak var testLabel6: UILabel!
    @IBOutlet weak var testLabel7: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.myTextFieldEditingDidEnd.delegate = self
        self.myTextFieldEditingChanged.delegate = self
        self.myTextFieldEditingDidBegin.delegate = self
        // Do any additional setup after loading the view.
    }
    //改行、または、Returnキーが押されたら呼び出されるメソッド
    func textFieldShouldReturn(_ textField:UITextField) -> Bool {
        //キーボードをしまう
        self.view.endEditing(true)
        return false
    }
    
    //今回追加
    func textFieldShouldBeginEditing(_ textField:UITextField) -> Bool {
        testEventLabel.text = "ShouldBeginEditing"
        return true
    }
    
    func textFieldDidBeginEditing(_ textField:UITextField) {
        testLabel2.text = "DidBeginEditing"
    }
    
    func textFieldShouldEndEditing(_ textField:UITextField) -> Bool {
        testLabel3.text = "ShouldEndEditing"
        testLabel5.text = "Clear"
        return true
    }
    
    func textFieldDidEndEditing(_ textField:UITextField){
        testLabel4.text = "DidEndEditing"
    }
    
    func textFieldShouldEndEditing(textField:UITextField) -> Bool {
        //            testLabel5.text = "ShouldEndEditing"
        return true
    }
    
    func textFieldShouldClear(_ textField:UITextField) -> Bool {
        testLabel6.text = "KeybordCloseBefore"
        //キーボードをしまう
        self.view.endEditing(true)
        
        testLabel7.text = "KeybordCloseAfter"
        return true
    }
}

class ConnectionInspectorViewContoroller: UIViewController {
    @IBOutlet weak var connectionTestLabel: UILabel!
    
    //下のボタン
    @IBAction func connectionTestAnyButton(_ sender: Any) {
        connectionTestLabel.text = "タッチダウン"
    }
    
    //上のボタン
    @IBAction func connectionTest1TouchupButton(_ sender: UIButton) {
        connectionTestLabel.text = "タッチアップ"
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

class SegmentedControllerViewController: UIViewController {
    
    @IBOutlet weak var segmentedLabel: UILabel!
    
    @IBOutlet weak var segmentedButton: UISegmentedControl!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    @IBAction func mySegmentedController(_ sender: UISegmentedControl) {
        
        //セグメント番号で条件分岐させる
        switch sender.selectedSegmentIndex {
        case 0:
            segmentedLabel.text = "おはようございます。"
        case 1:
            segmentedLabel.text = "こんにちは"
        case 2:
            segmentedLabel.text = "こんばんは"
        default:
            print("該当無し")
        }
    }
}

class SliderViewController: UIViewController {
    
    @IBOutlet weak var testSliderLabel: UILabel!
    
    //値変更スライダー
    @IBAction func testSlider(_ sender: UISlider) {
        //値を定義
        let test = sender.value
        if(test == sender.minimumValue){
            testSliderLabel.text = "最小値"
        } else if(test == sender.maximumValue){
            testSliderLabel.text = "最大値"
        } else {
            testSliderLabel.text = "\(test)"
        }
    }
    
    //透明度スライダー
    @IBAction func alphaSlider(_ sender: UISlider) {
        
        _ = 0.5
        //値を定義
        let test = sender.value
        if(test == sender.minimumValue){
            testSliderLabel.layer.opacity = test
            testSliderLabel.text = "最小値"
        } else if(test == sender.maximumValue){
            testSliderLabel.layer.opacity = test
            testSliderLabel.text = "最大値"
        } else {
            testSliderLabel.layer.opacity = test
            testSliderLabel.text = "\(test)"
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

class UISwitchViewController: UIViewController,AVAudioPlayerDelegate {
    
    var player1: AVAudioPlayer?
    var player2: AVAudioPlayer?
    var player3: AVAudioPlayer?
    var player4: AVAudioPlayer?
    var player5: AVAudioPlayer?
    
    @IBOutlet weak var testSwitchLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    func playBtn1() {
        if let sound1 = NSDataAsset(name: "yume") {
            player1 = try? AVAudioPlayer(data: sound1.data)
            player1?.numberOfLoops = -1 //無限ループ
            player1?.play()
        }
    }
    
    func stopBtn1() {
        player1?.stop()
    }
    
    func playBtn2() {
        if let sound2 = NSDataAsset(name: "seishishitauchu") {
            player2 = try? AVAudioPlayer(data: sound2.data)
            player2?.numberOfLoops = -1 //無限ループ
            player2?.play()
        }
    }
    
    func stopBtn2() {
        player2?.stop()
    }
    
    func playBtn3() {
        if let sound3 = NSDataAsset(name: "natsunokiri") {
            player3 = try? AVAudioPlayer(data: sound3.data)
            player3?.numberOfLoops = -1 //無限ループ
            player3?.play()
        }
    }
    
    func stopBtn3() {
        player3?.stop()
    }
    
    func playBtn4() {
        if let sound4 = NSDataAsset(name: "fukakukuraiido") {
            player4 = try? AVAudioPlayer(data: sound4.data)
            player4?.numberOfLoops = -1 //無限ループ
            player4?.play()
        }
    }
    
    func stopBtn4() {
        player4?.stop()
    }
    
    func playBtn5() {
        if let sound5 = NSDataAsset(name: "natsuyasuminotanken") {
            player5 = try? AVAudioPlayer(data: sound5.data)
            player5?.numberOfLoops = -1 //無限ループ
            player5?.play()
        }
    }
    
    func stopBtn5() {
        player5?.stop()
    }
    
    @IBAction func myUISwitch(_ sender: UISwitch) {
        if (sender.isOn){
            playBtn1()
        } else {
            stopBtn1()
        }
    }
    
    @IBAction func uchuSwitch(_ sender: UISwitch) {
        if (sender.isOn){
            stopBtn1()
            playBtn2()
        } else {
            stopBtn2()
        }
    }
    
    @IBAction func summerFogSwitch(_ sender: UISwitch) {
        if (sender.isOn){
            stopBtn1()
            playBtn3()
        } else {
            stopBtn3()
        }
    }
    
    @IBAction func darkenWaterSwitch(_ sender: UISwitch) {
        if (sender.isOn){
            stopBtn1()
            playBtn4()
        } else {
            stopBtn4()
        }
    }
    
    @IBAction func summerQuestSwitch(_ sender: UISwitch) {
        if (sender.isOn){
            stopBtn1()
            playBtn5()
        } else {
            stopBtn5()
        }
    }
}

class ActiveIndicatorViewController: UIViewController {
    
    @IBAction func myActivityViewReloadButton(_ sender: UIButton) {
        
        if(myActiveIndicator.isAnimating == true) {
            myActiveIndicator.stopAnimating()
        } else {
            //ここを変更
            //            myActiveIndicator.isHidden = true
            myActiveIndicator.startAnimating()
        }
    }
    
    @IBOutlet weak var myActiveIndicator: UIActivityIndicatorView!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    @IBOutlet weak var activeIndicatorMedium: UIActivityIndicatorView!
    
    @IBAction func activeIndicatorMediumSwitch(_ sender: UISwitch) {
        if (sender.isOn) {
            activeIndicatorMedium.startAnimating()
        } else {
            activeIndicatorMedium.stopAnimating()
        }
    }
    @IBOutlet weak var activeIndicatorWhiteLarge: UIActivityIndicatorView!
    
    @IBAction func activeIndicatorWhiteLargeSwitch(_ sender: UISwitch) {
        if (sender.isOn) {
            activeIndicatorWhiteLarge.startAnimating()
        } else {
            activeIndicatorWhiteLarge.stopAnimating()
        }
    }
    
    @IBOutlet weak var activeIndicatorGray: UIActivityIndicatorView!
    @IBAction func activeIndicatorGraySwitch(_ sender: UISwitch) {
        if (sender.isOn) {
            activeIndicatorGray.startAnimating()
        } else {
            activeIndicatorGray.stopAnimating()
        }
    }
}

class ProgressViewController: UIViewController {
    
    override func viewDidLoad() {
        
        //太く
        myProgressView.transform = CGAffineTransformMakeScale(1.0, 10.0)
        
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    @IBOutlet weak var myProgressLabel: UILabel!
    
    @IBOutlet weak var myProgressView: UIProgressView!
    
    
    @IBAction func myProgressButton(_ sender: UIButton) {
        
        //現在の進捗に10%を加算する。
        myProgressView.setProgress(myProgressView.progress + 0.1, animated: true)
        
        //ラベルに進捗率を表示する。
        myProgressLabel.text = "\(Int(myProgressView.progress * 100))%完了"
    }
    
    /*https://dev.classmethod.jp/articles/ios-uiprogressview-progress/
     を追加
     */
    private func reset() {
        myProgressView.progress = 0.1
    }
    
    private func setProgress(progress: Float, animated: Bool) {
        CATransaction.setCompletionBlock {
            NSLog("終了")
        }
        myProgressView.setProgress(progress, animated: animated)
        NSLog("開始")
    }
    
    @IBAction func noAnimation0Button(_ sender: UIButton) {
        setProgress(progress: 1.0, animated: false)
    }
    
    @IBAction func noAnimation5Button(_ sender: UIButton) {
        setProgress(progress: 5.0, animated: false)
    }
    
    @IBAction func noAnimation10Button(_ sender: UIButton) {
        setProgress(progress: 10.0, animated: false)
    }
    
    @IBAction func animation0Button(_ sender: UIButton) {
        setProgress(progress: 1.0, animated: true)
    }
    
    @IBAction func animation5Button(_ sender: UIButton) {
        setProgress(progress: 5.0, animated: true)
    }
    @IBAction func animation10Button(_ sender: UIButton) {
        setProgress(progress: 10.0, animated: true)
    }
    
    @IBAction func progressResetButton(_ sender: UIButton) {
        reset()
    }
}

class PageContorolViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        myPageControlLabel.text = ""
    }
    
    @IBOutlet weak var myPageControlLabel: UILabel!
    
    @IBAction func myPageControl(_ sender: UIPageControl) {
        myPageControlLabel.text = "\(sender.currentPage + 1)/\(sender.numberOfPages)"
    }
}

class StepperViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        myStepperLabel.text = "ステッパー増減値"
    }
    
    @IBOutlet weak var myStepperLabel: UILabel!
    
    @IBOutlet weak var akebonoMessageLabel: UILabel!
    @IBAction func myStepper(_ sender: UIStepper) {
        myStepperLabel.text = " \(17 + sender.value) "
        
        akebonoMessageLabel.font = akebonoMessageLabel.font.withSize(17 + sender.value)
    }
    
}

class AutoLayout1ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class AutoLayout2ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class AutoLayout3ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class AutoLayout4ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

class TableViewController: UIViewController, UITableViewDataSource {
    
    //表示データ
    var dataList = ["青山","阿部", "加藤","川島","神田","佐藤","坂田", "田中","千種","津崎","手嶋","中原","西山","羽鳥","平家","間宮","水野","武藤","元山","矢野",]
    
    //データを返すメソッド(スクロールなどでページを更新する必要が出るたびに呼び出される)
    //自動追加されたstubs
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell", for:indexPath) as UITableViewCell
        cell.textLabel?.text = dataList[indexPath.row]
        return cell
    }
    
    //データの個数を返すメソッド
    //自動追加されたstubs
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class TableView2Controller: UIViewController, UITableViewDataSource {
    
    //データ
    var dataInSection = [["青山","阿部"], ["加藤","川島","神田"], ["佐藤","坂田"], ["田中","千種","津崎","手嶋"],["中原","西山"],["羽鳥","平家"],["間宮","水野","武藤","元山"],["矢野"]]
    //セクション
    var sectionIndex:[String] = ["あ行", "か行", "さ行", "た行","な行", "は行", "ま行", "や行"]
    //セクション名を返す
    func tableView(_ tableView:UITableView, titleForHeaderInSection section:Int) -> String?{
        return sectionIndex[section]
    }
    //セクションの個数を返す
    func numberOfSections(in tableView: UITableView) -> Int {
        return sectionIndex.count
    }
    //データを返す
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell2", for:indexPath) as UITableViewCell
        let test = dataInSection[indexPath.section]
        cell.textLabel?.text = test[indexPath.row]
        return cell
    }
    //データの個数を返す
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataInSection[section].count
    }
    
    //セクション名の配列を返す
    func sectionIndexTitles(for tableView: UITableView) -> [String]? {
        return sectionIndex
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class TableCellViewController: UIViewController, UITableViewDataSource {
    @IBOutlet weak var myTableView: UITableView!
    //データ
    var dataList = ["青山","阿部","加藤","川島","神田","佐藤","坂田","田中"]
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellName:String
        
        //偶数行と奇数行で原型セルを変更する。
        if (indexPath.row % 2 == 0) {
            cellName = "TableCell1"
        } else {
            cellName = "TableCell2"
        }
        let cell = tableView.dequeueReusableCell(withIdentifier: cellName, for:indexPath) as UITableViewCell
        cell.textLabel?.text = dataList[indexPath.row]
        return cell
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class TableCellStyleViewController: UIViewController, UITableViewDataSource {
    
    @IBOutlet weak var styleTableView: UITableView!
    
    //データ
    var dataList = ["青山,一塁手","阿部,捕手","加藤,二塁手","神田,三塁手","佐藤,遊撃手","坂田,外野手"]
    
    //データを返すメソッド
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //セルを取得する。
        let cell = tableView.dequeueReusableCell(withIdentifier: "StyleCell", for:indexPath as IndexPath) as UITableViewCell
        
        //データをカンマで分割する。
        let arr = dataList[indexPath.row].components(separatedBy: ",")
        cell.textLabel?.text = arr[0] //タイトル
        cell.detailTextLabel?.text = arr[1]  //詳細文
        return cell
    }
    
    //データの個数を返すメソッド
    func tableView(_ tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
        return dataList.count
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class TableCellCustomViewController: UIViewController, UITableViewDataSource {
    
    //データ
    var dataList = ["青山,一塁手","阿部,捕手","加藤,二塁手","神田,三塁手","佐藤,遊撃手","坂田,外野手"]
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //セルを取得する。
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for:indexPath) as UITableViewCell
        
        //Tag番号でセルに含まれるラベルを取得する。
        let label1 = cell.viewWithTag(1) as! UILabel
        let label2 = cell.viewWithTag(2) as! UILabel
        let label3 = cell.viewWithTag(3) as! UILabel
        
        //データをカンマで分割する。
        let arr = dataList[indexPath.row].components(separatedBy: ",")
        
        //ラベルに値を設定する。
        label1.text = String(indexPath.row)
        label2.text = arr[0]
        label3.text = arr[1]
        
        //セルを選択したときの色を指定する。
        let colorView = UIView()
        colorView.backgroundColor = UIColor(red:0.8, green:0.7, blue:0.6, alpha:1.0)
        cell.selectedBackgroundView = colorView
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class TableDelegateViewController: UIViewController,UITableViewDataSource, UITableViewDelegate {
    @IBOutlet weak var delegateLabel: UILabel!
    //データ
    var dataList = ["青山","阿部","加藤","神田","佐藤","坂田"]
    //データの個数を返すメソッド
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    //データの個数を返すメソッド
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //セルを取得する。
        let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell", for:indexPath) as UITableViewCell
        
        cell.textLabel?.text = dataList[indexPath.row]
        return cell
    }
    //ハイライト前に呼び出されるメソッド
    func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool
    {
        print("1 ハイライト前")
        return true
    }
    //ハイライト後に呼び出されるメソッド
    func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath)
    {
        print("2 ハイライト後")
    }
    //ハイライト解除後に呼び出されるメソッド
    func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath)
    {
        print("3 ハイライト解除後")
    }
    //データ選択前に呼び出されるメソッド
    func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath?
    {
        print("4 データ選択前")
        return indexPath
    }
    //データ選択後に呼び出されるメソッド
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
        let selectData = tableView.cellForRow(at: indexPath as IndexPath)!.textLabel!.text
        delegateLabel.text = "\(selectData!)さんが呼び出されました。"
        print("5 データ選択後")
    }
    //データ選択解除前に呼び出されるメソッド
    func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath?
    {
        print("6 データ選択解除前")
        return indexPath
    }
    //データ選択解除後に呼び出されるメソッド
    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
    {
        print("7 データ選択解除後")
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class TableEditModeViewController: UIViewController, UITableViewDataSource {
    //データ
    @IBOutlet weak var editButton: UIButton!
    var dataList = ["青山","阿部","加藤","神田","佐藤","坂田"]
    @IBAction func changeModeButton(_ sender: UIButton) {
        //通常モードと編集モードを切り替える。
        if(editableTableView.isEditing == true) {
            editableTableView.isEditing = false
            editButton.setTitle("編集on", for: .normal)
        } else {
            editableTableView.isEditing = true
            editButton.setTitle("編集off", for: .normal)
        }
    }
    @IBOutlet weak var editableTableView: UITableView!
    //データの個数を返すメソッド
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    //データを返すメソッド
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //セルを取得する。
        let cell = tableView.dequeueReusableCell(withIdentifier: "EditCell", for:indexPath) as UITableViewCell
        cell.textLabel?.text = dataList[indexPath.row]
        return cell
    }
    //テーブルビュー編集時に呼ばれるメソッド
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        //削除の場合、配列からデータを削除する。
        if( editingStyle == UITableViewCell.EditingStyle.delete) {
            dataList.remove(at: indexPath.row)
        }
        //テーブルの再読み込み
        tableView.reloadData()
    }
    //編集可否を答えるメソッド:下の並び替え可否を答えるメソッドと競合するのでいずれかのみ
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        //最初の2行は削除不可にする。
        if(indexPath.row < 2) {
            return false
        } else {
            return true
        }
    }
    //並び替え時に呼ばれるメソッド
    func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath){
        //移動されたデータを取得する。
        let moveData = tableView.cellForRow(at: sourceIndexPath as IndexPath)?.textLabel!.text
        //元の位置のデータを配列から削除する。
        dataList.remove(at: sourceIndexPath.row)
        //移動先の位置にデータを配列に挿入する。
        dataList.insert(moveData!, at: destinationIndexPath.row)
    }
    //並び替え可否を答えるメソッド:上の編集可否を答えるメソッドと競合するのでいずれかのみ
    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        let orderData = dataList[indexPath.row]
        //青山さん以外の行は並び替え不可にする。
        if(orderData != "青山") {
            return false
        } else {
            return true
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        editButton.setTitle("編集on", for: .normal)
    }
}

class TableXIBViewController: UIViewController, UITableViewDataSource {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //自作セルをテーブルビューに登録する。
        let testXib = UINib(nibName:"TableViewCell", bundle:nil)
        xibTableView.register(testXib, forCellReuseIdentifier:"TestCell")
    }
    
    @IBOutlet weak var xibTableView: UITableView!
    
    //データ
    var dataList = ["青山,一塁手","阿部,捕手","加藤,二塁手","神田,三塁手","佐藤,遊撃手","坂田,外野手"]
    
    
    //データを返すメソッド
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //セルを取得する。
        let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell", for:indexPath as IndexPath) as! TableViewCell
        
        //データをカンマで分割する。
        let arr = dataList[indexPath.row].components(separatedBy: ",")
        
        cell.redTablecellLabel?.text = String(indexPath.row)
        cell.blueTablecellLabel?.text = arr[0]
        cell.blackTablecellLabel?.text = arr[1]
        
        return cell
    }
    
    //データの個数を返すメソッド
    func tableView(_ tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
        return dataList.count
    }
}

class TableKeyboardViewController: UIViewController,UITableViewDataSource,TableKeyboardDelegate{
    
    @IBOutlet weak var keyboardTableView: UITableView!
    
    //データ
    var dataList = ["青山","阿部","加藤","神田","佐藤","坂田"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //自作セルをテーブルビューに登録する。
        let testXib = UINib(nibName:"TableViewKeyboardCell", bundle:nil)
        keyboardTableView.register(testXib, forCellReuseIdentifier:"TestCell")
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //セルを取得して値を設定する。
        let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell", for:indexPath) as! TableViewKeyboardCell
        cell.tableTextField.text = dataList[indexPath.row]
        
        //自作セルのデリゲート先に自分を設定する。
        cell.delegate = self
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    
    func textFieldDidEndEditing(cell: TableViewKeyboardCell, value: String) {
        //変更されたセルのインデックスを取得する。
        let index = keyboardTableView.indexPathForRow(at: cell.convert(cell.bounds.origin, to:keyboardTableView))
        //データを変更する。
        dataList[index!.row] = value
        print(dataList)
    }
}

XIB側

import UIKit

class TableViewCell: UITableViewCell {

    @IBOutlet weak var redTablecellLabel: UILabel!
    
    @IBOutlet weak var blueTablecellLabel: UILabel!
    
    @IBOutlet weak var blackTablecellLabel: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
    
}

import UIKit

//デリゲート先に適用してもらうプロトコル
protocol TableKeyboardDelegate {
    func textFieldDidEndEditing(cell:TableViewKeyboardCell, value:String)
}

class TableViewKeyboardCell: UITableViewCell,UITextFieldDelegate {
    
    @IBOutlet weak var tableTextField: UITextField!
    
    var delegate:TableKeyboardDelegate! = nil
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
        //テキストフィールドのデリゲート先を自分に設定する。
        tableTextField.delegate = self
        
    }
    
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
    
    //デリゲートメソッド
    func textFieldShouldReturn(_ textField: UITextField) -> Bool
    {
        //キーボードを閉じる。
        textField.resignFirstResponder()
        return true
    }
    
    
    //デリゲートメソッド
    func textFieldDidEndEditing(_ textField: UITextField) {
        //テキストフィールドから受けた通知をデリゲート先に流す。
        self.delegate.textFieldDidEndEditing(cell: self, value: textField.text!)
    }
    
}



この記事が気に入ったらサポートをしてみませんか?