3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-10-08

このエントリ(【Swift】 タブブラウザライクに、任意のボタンを押した際に対応するViewを最前面に表示する)の続きとして、各タブに「タブを閉じるボタン」をつけました。

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

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

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

3つのタブが表示された状態
Simulator Screen Shot - iPad Air 2 - 2019-10-08 at 08.32.24.png
「tabNumber2」以外を閉じた状態
Simulator Screen Shot - iPad Air 2 - 2019-10-08 at 08.32.41.png

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

#####ソースコード

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

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

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だったので、一応補足まで。

    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"のように開くタブが指定されているリンクがあるので、それをきちんと制御してあげるにはどうしたらいいかが課題かなと思っています。

引き続き頑張ります。

以上です。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?