UISearchBarとUITableViewでお気に入り機能の様なプログラムを作ってみた

#今回の内容

<img width="150" alt="0AF728FB-2DF3-482F-BE72-2D899F476562_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/e3bd717d-fb25-7663-6696-027827bf9eeb.jpeg"> <img width="149" alt="CFC46E97-CC98-48AA-BB3F-E2C79259FD3A_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/a05da839-4bf9-6978-cde4-9c0465fdeb7e.jpeg"> <img width="150" alt="BB505A5F-8D30-494B-A4BB-5850A1B6049F_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/ed42cc81-86d0-210c-2e62-5a2548b8af60.jpeg"> <img width="147" alt="A8359FE1-0266-414D-9C5E-83B9335B02E9_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/2d5143e9-4655-6f5f-5f5d-2e48560ef2de.jpeg">

#コード

* コピペだけで試せるので実際に動かしてみてください
* 数字以外を`searchBar.searchTextField`に入力するとアプリが落ちます。

```Swift:ViewController
import UIKit

class ViewController: UIViewController {
    
    let searchBar = UISearchBar()
    let tableView = UITableView()
    let bookMarkListView = UITableView()
    
    var tableViewContentsArray = [Int](0...100)
    var bookMarkContentsArray:[String] = []
    var textDidChangeResultArray:[Int] = []
    
    var searchBool = Bool()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        searchBar.delegate = self
        searchBar.searchTextField.delegate = self
        searchBar.showsBookmarkButton = true
        searchBar.showsCancelButton = true
        view.addSubview(searchBar)
        
        tableView.delegate = self
        tableView.dataSource = self
        tableView.tag = 1
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        view.addSubview(tableView)
        
        bookMarkListView.delegate = self
        bookMarkListView.dataSource = self
        bookMarkListView.backgroundColor = .systemGray
        bookMarkListView.tag = 2
        bookMarkListView.register(UITableViewCell.self, forCellReuseIdentifier: "BookMarkCell")
        view.addSubview(bookMarkListView)
        
    }

    override func viewWillLayoutSubviews() {
        
        searchBar.frame = CGRect(x: view.frame.minX, y: view.frame.minY + view.safeAreaInsets.top, width: view.frame.size.width, height: 44)
        
        tableView.frame = CGRect(x: view.frame.minX, y: searchBar.frame.origin.y + searchBar.frame.size.height, width: view.frame.width, height: view.frame.size.height - (searchBar.frame.origin.y + searchBar.frame.size.height))
        
        bookMarkListView.frame = CGRect(x: view.frame.minX - (view.frame.size.width / 2), y: tableView.frame.origin.y, width: tableView.frame.size.width / 2, height: tableView.frame.height)
    }
    
}

extension ViewController:UITextFieldDelegate{
    
    func textFieldShouldClear(_ textField: UITextField) -> Bool {
        
        if bookMarkListView.frame.origin.x == view.frame.minX{
            
            UITableView.animate(withDuration: 0.6, delay: 0, options: .curveEaseInOut, animations: {self.bookMarkListView.frame.origin.x = self.view.frame.minX - (self.view.frame.size.width / 2)}, completion: nil)
        }
        
        return true
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        
        textField.resignFirstResponder()
        return true
    }
}

extension ViewController:UISearchBarDelegate{
    
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        
        if searchBar.text == ""{
            
            textDidChangeResultArray = []
            searchBool = false
            tableView.reloadData()
            return
        }
        
            textDidChangeResultArray = []
            textDidChangeResultArray = tableViewContentsArray.filter{ content in
                
                if String(content).contains(searchBar.text!) == true{
                    
                    return true
                }else{
                    
                    return false
                }
            }
            
            print(textDidChangeResultArray)
            searchBool = true
            tableView.reloadData()
    }
    
    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        
        searchBar.text = ""
        textDidChangeResultArray = []
        searchBool = false
        tableView.reloadData()
        
    }

    func searchBarBookmarkButtonClicked(_ searchBar: UISearchBar) {
        
        if bookMarkListView.frame.origin.x == view.frame.minX - (view.frame.size.width / 2){
            
        UITableView.animate(withDuration: 0.6, delay: 0, options: .curveEaseInOut, animations: {self.bookMarkListView.frame.origin.x = self.view.frame.minX}, completion: nil)
            
        }else if bookMarkListView.frame.origin.x == view.frame.minX{
            
            UITableView.animate(withDuration: 0.6, delay: 0, options: .curveEaseInOut, animations: {self.bookMarkListView.frame.origin.x = self.view.frame.minX - (self.view.frame.size.width / 2)}, completion: nil)
        }
    }
}


extension ViewController:UITableViewDelegate{
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
        switch tableView.tag{
        
        case 1: return
            
        case 2:
            let selectCell = tableView.cellForRow(at: indexPath)
            searchBar.text = selectCell?.textLabel?.text
            textDidChangeResultArray = []
            textDidChangeResultArray = tableViewContentsArray.filter{ content in
                
                if String(content).contains(searchBar.text!) == true{
                    
                    return true
                }else{
                    
                    return false
                }
            }
            
            print(textDidChangeResultArray)
            searchBool = true
            self.tableView.reloadData()
            
            if bookMarkListView.frame.origin.x == view.frame.minX{
                
                UITableView.animate(withDuration: 0.6, delay: 0, options: .curveEaseInOut, animations: {self.bookMarkListView.frame.origin.x = self.view.frame.minX - (self.view.frame.size.width / 2)}, completion: nil)
            }
            
        default: break
        }
    }
}

extension ViewController:UITableViewDataSource{
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        
        return tableView.frame.size.height / 10
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        var returnInt = Int()
        
        switch tableView.tag{
        
        case 1:
            returnInt = {() -> Int in
                
            if textDidChangeResultArray.count > 0{
                
                return textDidChangeResultArray.count
            }else{
                
                return tableViewContentsArray.count
            }
        }()
            
        case 2:
            returnInt = bookMarkContentsArray.count
            
        default:
            returnInt = 0
        }
        
        return returnInt
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        return {() -> UITableViewCell in
            
            var retunCell = UITableViewCell()
            
            switch tableView.tag {
            
            case 1:
                let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
                
                cell.textLabel?.text = {() -> String in
                    
                    if textDidChangeResultArray.count > 0{
                        
                        return String(textDidChangeResultArray[indexPath.row])
                    }else{
                        
                        return String(tableViewContentsArray[indexPath.row])
                    }
                }()
                cell.accessoryView = {() -> UISwitch in
                    
                    let uiSwitch = UISwitch()
                    uiSwitch.frame.origin = CGPoint(x: cell.frame.maxX - (uiSwitch.frame.width + 5), y: cell.frame.midY - (uiSwitch.frame.size.height / 2))
                    uiSwitch.addTarget(self, action: #selector(bookMarkRegistration), for: .valueChanged)
                    uiSwitch.tag = indexPath.row
                    uiSwitch.isOn = {() -> Bool in
                        
                        switch searchBool{
                        
                        case true:
                            if bookMarkContentsArray.contains(String(textDidChangeResultArray[indexPath.row])){

                                return true
                            }else{

                                return false
                            }
                            
                        case false:
                            if bookMarkContentsArray.contains(String(tableViewContentsArray[indexPath.row])){

                                return true
                            }else{

                                return false
                            }
                        }

                    }()
                    
                    return uiSwitch
                }()
                retunCell = cell
                
            case 2:
                let cell = tableView.dequeueReusableCell(withIdentifier: "BookMarkCell", for: indexPath)
                
                if bookMarkContentsArray.count >= 1{
                        
                    cell.textLabel?.text = bookMarkContentsArray[indexPath.row]
                }
                
                cell.textLabel?.textColor = .white
                cell.backgroundColor = .systemGray
                retunCell = cell
                
            default:
                break
            }
            return retunCell
        }()
        
    }
    
    @objc func bookMarkRegistration(sender:UISwitch){
        
        switch sender.isOn{
        
        case true:
            if searchBool == true{
                
                bookMarkContentsArray.append(String(textDidChangeResultArray[sender.tag]))
                self.bookMarkListView.reloadData()
            }else if searchBool == false{
                
                bookMarkContentsArray.append(String(tableViewContentsArray[sender.tag]))
                self.bookMarkListView.reloadData()
            }
           
        case false:
            if searchBool == true{
                
                bookMarkContentsArray.removeAll(where: {$0 == String(textDidChangeResultArray[sender.tag])})
                bookMarkListView.reloadData()
            }else if searchBool == false{
                
                bookMarkContentsArray.removeAll(where: {$0 == String(tableViewContentsArray[sender.tag])})
                bookMarkListView.reloadData()
            }

        }
    }
    
}
```
# 終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。