見出し画像

【徒然iOS】気ままにUIKit91〜NGサンプル Search Bar 検索を補助してくれる部品を追加〜

概要

このマガジンは四十を過ぎたおっさんが、

を参考にStoryboardでiOSアプリを完全に趣味で楽しんでいるだけな記事を気ままに上げてます。

今回

をハイ、レッツゴ🕺

前準備

念の為、

  1. バックアップ

  2. 新しいクラス

  3. ビューコントローラの追加

をいつも通りやってから本題へ💃

こんな感じかな💦

本題

サーチバーのアトリビュートインスペクタの設定項目

てことなんで、今回も毎度恒例の、

一覧表がメイン

だね〜〜〜〜
ただし、後半に、前回のビューを使ったコードもあるみたいなんで、、、

⒈前回の機能を今回の新規ビューにも組み込む

を参考に〜〜〜〜

ハイ、出来た🕺

⒉一覧表〜〜〜〜

とりあえず、ここの項目ちゃん達らしいが、、、、
なっが!!!!!
て、ことは
相当いろいろなことができるってことね🕺
表としてはこんな感じか🤔

とりあえず、設定を一部触って遊んでみると

こんな感じだけど、出るとこと出ないところとかあるね👀
おそらく、各項目の組み合わせ次第って感じか🤔

てな感じで、色々動かしながら、

自分で遊んでみるのが一番

なので、今回もコードのところだけ〜〜〜〜

Scope Titles

⒈設定にチェックを入れる〜〜〜

ココな🕺

⒉コード組み込み

//
//  ViewController.swift
//
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UISearchBarDelegate{
    @IBOutlet weak var testTableView: UITableView!
    @IBOutlet weak var testSearchBar: UISearchBar!
    //データ
    let dataList = ["月刊コロコロコミック(小学館)",
        "コロコロイチバン!(小学館)",
        "最強ジャンプ(集英社)",
        "Vジャンプ(集英社)",
        "週刊少年サンデー(小学館)",
        "週刊少年マガジン(講談社)",
        "週刊少年ジャンプ(集英社)",
        "週刊少年チャンピオン(秋田書店)",
        "月刊少年マガジン(講談社)",
        "月刊少年チャンピオン(秋田書店)",
        "月刊少年ガンガン(スクウェア)",
        "月刊少年エース(KADOKAWA)",
        "月刊少年シリウス(講談社)",
        "週刊ヤングジャンプ(集英社)",
        "ビッグコミックスピリッツ(小学館)",
        "週刊ヤングマガジン(講談社)"]
    let scopeList = ["週刊","月刊","その他"]
    //検索結果配列
    var searchResult = [String]()
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //デリゲート先を自分に設定する。
        testSearchBar.delegate = self
        //何も入力されていなくてもReturnキーを押せるようにする。
        testSearchBar.enablesReturnKeyAutomatically = false
        //スコープのタイトルを設定する。
        testSearchBar.scopeButtonTitles = scopeList
        //検索結果配列にデータをコピーする。
        searchResult = dataList
    }
    //データを返すメソッド
    func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath:NSIndexPath) -> UITableViewCell {
        //セルを取得する。
        let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath:indexPath) as UITableViewCell
        cell.textLabel?.text = searchResult[indexPath.row]
        return cell
    }
    //データの個数を返すメソッド
    func tableView(tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
        return searchResult.count
    }
    //検索ボタン押下時の呼び出しメソッド
    func searchBarSearchButtonClicked(searchBar: UISearchBar) {
        //キーボードを閉じる。
        testSearchBar.endEditing(true)
    }
    //スコープ変更時の呼び出しメソッド
    func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
        self.searchBar(searchBar, textDidChange:testSearchBar.text!)
    }
    //テキスト変更時の呼び出しメソッド
    func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
        //検索結果配列を空にする。
        searchResult.removeAll()
        if(testSearchBar.text == "") {
            //検索文字列が空の場合はすべてを表示する。
            searchResult = dataList
        } else {
            //検索文字列とスコープを含むデータを検索結果配列に追加する。
            for data in dataList {
                if (data.containsString(searchText) && data.containsString(scopeList[searchBar.selectedScopeButtonIndex]) ){
                    searchResult.append(data)
                }
            }
        }
        //テーブルを再読み込みする。
        testTableView.reloadData()
    }    
}

を参考に〜〜〜書き換え〜〜〜

とここで、

ScopeTitles自体がシミュレータでも実機でも表示されなくなってる🤔

なので、コードだけ記載しておく〜〜〜〜🕺

今回のコード(バグコード。現在の書き方)

書き替えの参考程度に見といてね〜〜〜

class SearchBarSettingsViewController: UIViewController,UITableViewDataSource, UISearchBarDelegate {
    @IBOutlet weak var mySearchBar: UISearchBar!
    @IBOutlet weak var myTableView: UITableView!
    //表示データ
    var dataList = [
        "月刊コロコロコミック(小学館)",
        "コロコロイチバン!(小学館)",
        "最強ジャンプ(集英社)",
        "Vジャンプ(集英社)",
        "週刊少年サンデー(小学館)",
        "週刊少年マガジン(講談社)",
        "週刊少年ジャンプ(集英社)",
        "週刊少年チャンピオン(秋田書店)",
        "月刊少年マガジン(講談社)",
        "月刊少年チャンピオン(秋田書店)",
        "月刊少年ガンガン(スクウェア)",
        "月刊少年エース(KADOKAWA)",
        "月刊少年シリウス(講談社)",
        "週刊ヤングジャンプ(集英社)",
        "ビッグコミックスピリッツ(小学館)",
        "週刊ヤングマガジン(講談社)"
    ]
    
    let scopeList = ["週刊","月刊","その他"]
    //検索結果配列
    var searchResult = [String]()
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //デリゲート先を自分に設定する。
        mySearchBar.delegate = self
        //何も入力されていなくてもReturnキーを押せるようにする。
        mySearchBar.enablesReturnKeyAutomatically = false
        //スコープのタイトルを設定する。
        mySearchBar.scopeButtonTitles = scopeList
        //検索結果配列にデータをコピーする。
        searchResult = dataList
    }
    //データの個数を返すメソッド
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return searchResult.count
    }
    //データを返すメソッド(スクロールなどでページを更新する必要が出るたびに呼び出される)
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //セルを取得する。
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableCell", for:indexPath) as UITableViewCell
        cell.textLabel?.text = searchResult[indexPath.row]
        return cell
    }
    //検索ボタン押下時の呼び出しメソッド
    @objc func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        //キーボードを閉じる。
        mySearchBar.endEditing(true)
    }
    //スコープ変更時の呼び出しメソッド
    @objc func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
        self.searchBar(searchBar, textDidChange:mySearchBar.text!)
    }
    //テキスト変更時の呼び出しメソッド
    @objc func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        //検索結果配列を空にする。
        searchResult.removeAll()
        if(mySearchBar.text == "") {
            //検索文字列が空の場合はすべてを表示する。
            searchResult = dataList
        } else {
            //検索文字列とスコープを含むデータを検索結果配列に追加する。
            for data in dataList {
                if (data.contains(searchText) && data.contains(scopeList[searchBar.selectedScopeButtonIndex]) ){
                    searchResult.append(data)
                }
            }
        }
        //テーブルを再読み込みする。
        myTableView.reloadData()
    }
}
週刊だけに固定されていて、、、
月で入力しても検索結果が出ない🤣
意味ね〜〜〜〜

今回のコード(極力、サンプルコードに従った書き方)

class SearchBarSettingsViewController: UIViewController,UITableViewDataSource, UISearchBarDelegate {
    @IBOutlet weak var mySearchBar: UISearchBar!
    @IBOutlet weak var myTableView: UITableView!
    //表示データ
    var dataList = [
        "月刊コロコロコミック(小学館)",
        "コロコロイチバン!(小学館)",
        "最強ジャンプ(集英社)",
        "Vジャンプ(集英社)",
        "週刊少年サンデー(小学館)",
        "週刊少年マガジン(講談社)",
        "週刊少年ジャンプ(集英社)",
        "週刊少年チャンピオン(秋田書店)",
        "月刊少年マガジン(講談社)",
        "月刊少年チャンピオン(秋田書店)",
        "月刊少年ガンガン(スクウェア)",
        "月刊少年エース(KADOKAWA)",
        "月刊少年シリウス(講談社)",
        "週刊ヤングジャンプ(集英社)",
        "ビッグコミックスピリッツ(小学館)",
        "週刊ヤングマガジン(講談社)"
    ]
    
    let scopeList = ["週刊","月刊","その他"]
    //検索結果配列
    var searchResult = [String]()
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //デリゲート先を自分に設定する。
        mySearchBar.delegate = self
        //何も入力されていなくてもReturnキーを押せるようにする。
        mySearchBar.enablesReturnKeyAutomatically = false
        //スコープのタイトルを設定する。
        mySearchBar.scopeButtonTitles = scopeList
        //検索結果配列にデータをコピーする。
        searchResult = dataList
    }
    //データの個数を返すメソッド
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return searchResult.count
    }
    //データを返すメソッド(スクロールなどでページを更新する必要が出るたびに呼び出される)
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //セルを取得する。
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableCell", for:indexPath) as UITableViewCell
        cell.textLabel?.text = searchResult[indexPath.row]
        return cell
    }
    //検索ボタン押下時の呼び出しメソッド
    func searchBarSearchButtonClicked(searchBar: UISearchBar) {
        //キーボードを閉じる。
        mySearchBar.endEditing(true)
    }
    //スコープ変更時の呼び出しメソッド
    func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
        self.searchBar(searchBar: searchBar, textDidChange:mySearchBar.text!)
    }
    //テキスト変更時の呼び出しメソッド
    func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
        //検索結果配列を空にする。
        searchResult.removeAll()
        if(mySearchBar.text == "") {
            //検索文字列が空の場合はすべてを表示する。
            searchResult = dataList
        } else {
            //検索文字列とスコープを含むデータを検索結果配列に追加する。
            for data in dataList {
                if (data.contains(searchText) && data.contains(scopeList[searchBar.selectedScopeButtonIndex]) ){
                    searchResult.append(data)
                }
            }
        }
        //テーブルを再読み込みする。
        myTableView.reloadData()
    }
    @IBAction func webButton(_ sender: Any) {
        let url = URL(string: searchBarStandardViewController)
        let safariView = SFSafariViewController(url: url!)
        present(safariView, animated: true)
    }
}
そもそも検索機能自体が、検索ボタン押しても動かね〜〜〜💦

ブラッシュアップ

今回も地球儀ボタンとAutoLayoutだけ〜〜〜

操作方法はわからない人は、

あたりを参考にしてね〜〜〜

記事公開後、

間違わないようにタイトルに注意書きを入れて〜〜〜
ハイ、完了💃
実機も問題無し🕺

Apple公式

さてと、次回は

をレッツゴする🕺

今回のポイント(ほぼ、ぼやき🤣)

ややこしいコードを自分で組める=理解してる=自分はできる

と勘違いしてる人が大半なんだけど、、、

  • Xcodeの仕様変更

  • Swiftコードの変更

  • 公開APIの追加

なんかで、使えなくなったり、大幅な書き換えが必要だったり、動きが変わったりする可能性もあるから、そもそもこんなコードは組まないで、

Xcodeの画面上でできることはXcodeの画面上でやる

ことを、Apple自体も、オイラがアプリ開発を始めた6年近く前は推奨してたし、

なんかにも載ってた💦なので、

こんなコードでのやらなくてもいいことは極力やらない方がいい。
(extensionで拡張してるわけではないので、拡張機能とは言わない)
すでに、動かなくなってるしね👀

てか、もはやコードでやりたいなら、こんな中途半端なフレームワークじゃなくって、

SwiftUIでやれば

て感じ👀

こんなこと言うと、

レガシーエンジニアとか、現場で根性とか精神論を口にする人
👉端的に言えば、無責任な立場か頭の悪い人

ほど、

ハイハイ、それは言い訳!
いやいや、そこで諦めずに調べるのがエンジニアだろ!!

みたいなことを言ってくるんだけど、調べ尽くして出来ないって言ってんだよね〜〜〜
そもそも開発環境の仕様変更かバグっぽいのに、根性でやりくりして、その場では実現できても、

また仕様変更入ったらどうすんの?👀
目先じゃなく、そこ考えて話してる?👀

て感じ👀

ま、どうしてもUIKitでこの機能をやってみたいって人は、

なんかを参考にしてみてね。
すでに、いくつか必要なプロトコルすら変わってるってことに気づくはず藁🤣
ま、このマガジンの趣旨に反するので、ここではやる気はないが💦

開発現場だと、

要求を出してくる側(クライアント)なんて、
大体、ネットで調べて今回みたいな記事を見つけて、
記事の公開年月日なんかもよく見ないで、

このサイトに載っていたから、今でもできる

って勝手に思い込んで言ってくる事が多い。ってか殆ど。
調べた結果で、

出来ないものは出来ない
設計や管理で余計な作業コストにしかならないから、やらない

って言うのもエンジニアの仕事。

ちょっと、動く物が作れるようになって、一端のエンジニア気取りで、

何でも出来ます。
みたいに豪語する駆け出しさんも世の中にはいるんだけど、

WEBに載ってる大半の情報って、経済学で言うところの

美人投票

みたいなもので、大体みなさん成功例しか載せないからね〜〜〜
知識が増えて、よくよく見ると、みんな同じようなサンプルしか出してないことに気づくし、、、だから、

の、

なんかで言われりゃ当たり前のことなんかをツラツラと書いてる次第。
ホントに誰もがその当たり前が出来てりゃ、こんな記事を書く必要なんてないんだが 藁🤣

独学でも学校出てても、業務経験があってもなくてもあんまり関係ないんだが、

ホントに、その開発言語に精通した知識で経験も積んでるエンジニアであれば、

30分以上悩んだり、やりくりなんてしないよ〜〜〜

それをやってる時点で

てな感じで、

継続したら危険

って経験からわかるからね。

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