見出し画像

【徒然iOS】気ままにUIKitコラム〜ものつくりが好きなら新しい言葉よりもモノを作ろう〜

概要

一昨年ぐらいから、ローコード?ノーコード?って言葉をよく聞く。

要は、

てことみたい。

わかっていない人ほどやたら、

①新しいトレンディな言葉(ローコードやノーコードみたいな)に拘る

②その言葉に付随するプログラミング言語(TypeScript、React)の経験があるかに拘る

んだよね〜〜〜!

新しい言葉を作って、その経験者を欲しがるのは勝手なんだけど、

2年くらい前に流行り出した言葉なのに、2年以上の経験を求められてもね〜〜〜
あれ系の経験者(GoogleAppsScriptなど)から言うと、結局、ローコードやノーコードで開発できない要求が出てきた場合にはコードを書かないといけなくなる宿命なんだよねえ。

顧客はどこまでが限界かなんか知らずに、どんどん要求レベルも量も上げてくる
からね。

少ないコードかコードなしで開発ができる

作業効率が上がる

て安易に考えて導入してる現場も多いみたいだけど、おそらく

沼とパワハラと炎上の嵐

だろうな。

少ないコードやコードなしでできるてことは 

  • できることに限界がある 
    or 

  • プラットフォームGUI機能に精通してないと作れない

からね〜〜〜!

トレンディな言葉を追うより、

オブジェクト指向言語に通底する考え方とか思想

を理解しておく方が大事。

  • キャメルケース

  • 継承

  • プロトコル

  • ジェネリクス

  • スタック

とかの概念を理解できてない人に、ReactでTypeScript(ローコード)、GoogleAppsScript(AppSheetでノーコード)の開発なんか任せても、結局、無駄なコードが多くなって大変だろうなと。

まとめ

どうせ何年かしたら、また新しい言葉が出来てるから、

いちいち気にしなくていい

プログラミングとかモノ作り自体ができないのに、自分はITわかってます、理解してます感を出したい人たちが勝手に色々、トレンドワードを生み出してるだけだから。
何年か前のマイナンバー、ビッグデータ、RPAしかりDX、EX、GXなどなど。
トレンドな言葉をいくら追ったり生み出したところで、ゼロから何かを生み出せないと意味ないからね〜〜〜。

そればかり気にしてる時点で、

どうせ本当はモノ作りがそこまで好きじゃないんでしょ

て感じ。

新しい言葉を追う暇があったら、

で感想書いてる、Code completeなんかの開発哲学系の本を読んだ方がよほど良い。

付録

「気ままにUIKit」の連載でこれまでに書いたコード

UIKitで15個くらいビューを作ってるんだけど、
今のところ組み込んだコードは

import UIKit
import AVFoundation

class ButtonViewControllerUIViewController{
    
    @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 TextFieldViewControllerUIViewController,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 ConnectionInspectorViewContorollerUIViewController {
    @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 SegmentedControllerViewControllerUIViewController {
    
    @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 SliderViewControllerUIViewController {
    
    @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 UISwitchViewControllerUIViewController,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 = tryAVAudioPlayer(data: sound1.data)
            player1?.numberOfLoops = -1 //無限ループ
            player1?.play()
        }
    }
    
    func stopBtn1() {
        player1?.stop()
    }
    
    func playBtn2() {
        if let sound2 = NSDataAsset(name: "seishishitauchu") {
            player2 = tryAVAudioPlayer(data: sound2.data)
            player2?.numberOfLoops = -1 //無限ループ
            player2?.play()
        }
    }
    
    func stopBtn2() {
        player2?.stop()
    }
    
    func playBtn3() {
        if let sound3 = NSDataAsset(name: "natsunokiri") {
            player3 = tryAVAudioPlayer(data: sound3.data)
            player3?.numberOfLoops = -1 //無限ループ
            player3?.play()
        }
    }
    
    func stopBtn3() {
        player3?.stop()
    }
    
    func playBtn4() {
        if let sound4 = NSDataAsset(name: "fukakukuraiido") {
            player4 = tryAVAudioPlayer(data: sound4.data)
            player4?.numberOfLoops = -1 //無限ループ
            player4?.play()
        }
    }
    
    func stopBtn4() {
        player4?.stop()
    }
    
    func playBtn5() {
        if let sound5 = NSDataAsset(name: "natsuyasuminotanken") {
            player5 = tryAVAudioPlayer(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 ActiveIndicatorViewControllerUIViewController {
    
    @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 ProgressViewControllerUIViewController {
    
    override func viewDidLoad() {
        
        //太く
        myProgressView.transform = CGAffineTransformMakeScale(1.010.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 PageContorolViewControllerUIViewController {
    
    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 StepperViewControllerUIViewController {
    
    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 AutoLayout1ViewControllerUIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class AutoLayout2ViewControllerUIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class AutoLayout3ViewControllerUIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

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

class TableViewControllerUIViewControllerUITableViewDataSource {
    
    //表示データ
    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 TableView2ControllerUIViewControllerUITableViewDataSource {
    
    //データ
    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 TableCellViewControllerUIViewControllerUITableViewDataSource {
    @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()
    }
}

くらいなもの。
UIKitでの開発がいかに少ないコードでひとつのビューが開発ができるかわかると思う。

ま、こういうの載せるとサンプルコードと勘違いして、
今までの記事も見ずに、コードだけベタ貼りして動かないと勝手に怒る人が居そうだけど、
今までの記事を読んでれば、そもそも、
ビューに配置した部品をコードに連結させないと動くわけがない
んだけどね。

さてと、

昨日、ちょっと後頭部が出血するくらいの頭を強打する事故にもあったし、
週末は文藝春秋の今月号も読みたいので、

💃本編はまた来週時間ができたらやります〜〜〜🕺

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