【Swift】 「タブを閉じる」ボタンの追加（自作タブブラウザアプリ開発）

このエントリ(<a href="https://qiita.com/ydzum1123/items/e164e2c647433c982140">【Swift】 タブブラウザライクに、任意のボタンを押した際に対応するViewを最前面に表示する</a>)の続きとして、各タブに「タブを閉じるボタン」をつけました。

####開発環境
端末:MacBook Pro/MacOS 10.14.5(Mojave)
Xcode:10.2.1
Swift:5

####やったこと(ポイント)
①各タブに「タブを閉じる」ボタンを追加

####実装
#####画面イメージ
各タブの左に、赤い「×」でボタンを付けています。

|３つのタブが表示された状態|
|:-:|
|<img width="400" alt="Simulator Screen Shot - iPad Air 2 - 2019-10-08 at 08.32.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/03ae9bb7-5809-6831-ca2e-702c223d7ca1.png">|

|「tabNumber2」以外を閉じた状態|
|:-:|
|<img width="400" alt="Simulator Screen Shot - iPad Air 2 - 2019-10-08 at 08.32.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126315/fbf8613c-65f7-c01b-e678-9de6f2e2fe0e.png">|

見た目では分からないですが、「×」ボタンを押すと、対応するタブボタンとそれに紐づいているWKWebViewも消えています。
あと、消したタブの右側にタブが存在する場合、ちゃんと左に詰められるようにしています。

#####ソースコード

冒頭にリンクを貼ったエントリから、修正した点は大きく２つです。
①タブに「閉じる(×)」ボタンを追加表示させる
②「閉じる」ボタン押下時の処理を追加する

それ以外の部分を割愛すると、以下のようなコードで実現しています。

```swift:ViewController.swift
import UIKit
import WebKit

class ViewController: UIViewController,
    WKNavigationDelegate,
    WKUIDelegate,
    UIScrollViewDelegate {
    
    ... // 前回のエントリに貼ったコードを参照。
    
    @objc func closeTab(sender: UIButton) {
        // webViewを消す
        let viewTag = sender.tag + 9000
        let targetView = view.viewWithTag(viewTag) as! WKWebView
        
        targetView.removeFromSuperview()
        
        // タブボタンを消す
        let btnTabTag = sender.tag - 1000
        let targetBtn = view.viewWithTag(btnTabTag) as! UIButton
        
        targetBtn.removeFromSuperview()
        
        // タブボタンにひっついていた「閉じる」ボタン自体も消す
        let btnCloseTabTag = sender.tag
        let targetBtnCloseTab = view.viewWithTag(btnCloseTabTag) as! UIButton
        
        targetBtnCloseTab.removeFromSuperview()
        
        // UIScrollViewの中身を残りのタブで配置しなおす
        originX = 0
        tabScrollView.frame = CGRect.init(x: 0,
                                          y: 44,
                                          width: viewWidth,
                                          height: 50)
        tabScrollView.contentSize = CGSize.init(width: 0,
                                                height: 50)

        for i in 1...tagNumber {
            if (view.viewWithTag(i) != nil) {
                let targetButton = view.viewWithTag(i) as! UIButton
                let targetButtonWidth:CGFloat = 200
                let targetButtonHeight:CGFloat = tabScrollView.frame.height
                
                // タブボタンの見た目設定
                targetButton.tag = i
                targetButton.layer.cornerRadius = 3.0
                targetButton.layer.borderWidth = 1.5
                targetButton.layer.borderColor = UIColor.init(red: 87/255, green: 144/255, blue: 40/255, alpha: 1).cgColor
                
                targetButton.backgroundColor = .white
                targetButton.setTitleColor(UIColor.init(red: 118/255, green: 197/255, blue: 57/255, alpha: 1), for: .normal)
                targetButton.titleLabel?.font = UIFont.systemFont(ofSize: 15)
                targetButton.addTarget(self,
                                    action: #selector(showView(sender: )),
                                    for: .touchUpInside)
                targetButton.frame = CGRect(x: originX,
                                         y: 0,
                                         width: targetButtonWidth,
                                         height: targetButtonHeight)
                
                // タブを閉じるボタン
                let closeTagNumber = i + 1000
                let targetCloseButton = view.viewWithTag(closeTagNumber) as! UIButton
                let targetCloseButtonWidth:CGFloat = 30
                let targetCloseButtonHeight:CGFloat = 30
                targetCloseButton.tag = closeTagNumber
                targetCloseButton.addTarget(self,
                                      action: #selector(closeTab(sender:)),
                                      for: .touchUpInside)
                targetCloseButton.frame = CGRect.init(x: originX + 160,
                                                y: 10,
                                                width: targetCloseButtonWidth,
                                                height: targetCloseButtonHeight)
                
                // スクロールバーの中のタブボタンの表示位置をずらす制御
                originX += targetButtonWidth
                
                tabScrollView.addSubview(targetButton)
                tabScrollView.addSubview(targetCloseButton)
                tabScrollView.contentSize = CGSize(width: originX,
                                                   height: targetButtonHeight)
                print("originX = " + originX.description)
                view.addSubview(tabScrollView)
            }
        }        
    }
        
    func addTab(url: URL) {

        ... // 前回のエントリに貼ったコードを参照。
        
        // タブを閉じるボタン
        let btnCloseTab = UIButton()
        let btnCloseTabWidth:CGFloat = 30
        let btnCloseTabHeight:CGFloat = 30
        btnCloseTab.tag = tagNumber + 1000
        btnCloseTab.titleLabel?.textAlignment = .center
        btnCloseTab.setTitle("×", for: .normal)
        btnCloseTab.setTitleColor(.red, for: .normal)
        btnCloseTab.addTarget(self,
                              action: #selector(closeTab(sender:)),
                              for: .touchUpInside)
        btnCloseTab.frame = CGRect.init(x: originX + 160,
                                        y: 10,
                                        width: btnCloseTabWidth,
                                        height: btnCloseTabHeight)
        
        // スクロールバーの中のタブボタンの表示位置をずらす制御
        originX += tabButtonWidth
        
        // タブボタンと、閉じるボタンをUIScrollViewに追加
        tabScrollView.addSubview(tabButton)
        tabScrollView.addSubview(btnCloseTab)
        tabScrollView.contentSize = CGSize(width: originX,
                                           height: tabButtonHeight)
        
        view.addSubview(tabScrollView)
        view.addSubview(webView)
        
        ...

    }
```

一応「閉じる」機能を実装できました。
他の良いやり方が思いつかないですが、なんかビミョーな感じはしてます。

###### 補足
細かいトコですが、前回のエントリではタブボタンの文字をタブ中央に配置していたんですが、「閉じる」ボタンの追加にあたり、左寄せにしました。

しかし、そのやり方が`UIButton.titleLabel.textAlignment = .left`ではなく、
`UIButton.contentHorizontalAlignment = .left`だったので、一応補足まで。

```swift
    let tabButton = UIButton()
    let tabButtonWidth:CGFloat = 200
    let tabButtonHeight:CGFloat = tabScrollView.frame.height

    // タブボタンの見た目設定
    tabButton.tag = tagNumber
    // この設定はあまり意味がなかった。
    // tabButton.titleLabel?.textAlignment = .center
    tabButton.contentHorizontalAlignment = .left
```


####感想など
「タブを閉じる」はできたので、次は「今開いてるタブはどれか」を示すために色を変えていたのを、タブを閉じた時にどう制御するかを考えていきます。
あと、実際動かしたいWebサービスでは、`target="hoge"`のように開くタブが指定されているリンクがあるので、それをきちんと制御してあげるにはどうしたらいいかが課題かなと思っています。

引き続き頑張ります。

以上です。