관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 1. WKWebView - UIToolBar 사용하여 뒤로가기, 앞으로가기 구현 (goBack(), goForward()) 본문

iOS 응용 (swift)

[iOS - swift] 1. WKWebView - UIToolBar 사용하여 뒤로가기, 앞으로가기 구현 (goBack(), goForward())

jake-kim 2021. 11. 6. 21:14

* WKWebView 기초 개념은 이곳 먼저 참고: https://ios-development.tistory.com/700

 

1. WKWebView - UIToolBar 사용하여 뒤로가기, 앞으로가기  구현 (goBack(), goForward())

2. WKWebView - cookie 설정, access token 송신, deeplink 수신 방법

3. WKWebView - 양방향 통신, WKUserScript, WKScriptMessageHandler 델리게이트를 구현하여 JavaScript interface 사용 방법


설계

  • UIViewController를 상속한 BaseViewController를 생성하고, 여기서 ToolBar에 들어갈 뒤로가기, 앞으로가기 UIBarButtonItem 인스턴스 생성
  • BaseViewController를 상속하는 새로운 WebViewController를 생성, WebViewController에는 WKWebView를 가지는 형태

BaseViewController

  • NavigationBar의 버튼과 UIToolBar를 정의
    • WebViewController에서 addBottomToolBar()를 호출하여 toolBar UI를 붙이는 형태
class BaseViewController: UIViewController {

    private lazy var backButton: UIButton = {
        let button = UIButton()
        button.setImage(backButtonImage, for: .normal)
        button.addTarget(self, action: #selector(didTapBackButton), for: .touchUpInside)
        return button
    }()

    private lazy var closeButton: UIButton = {
        let button = UIButton()
        button.setImage(closeButtonImage, for: .normal)
        button.addTarget(self, action: #selector(didTapCloseButton), for: .touchUpInside)
        return button
    }()

    private lazy var navigationTitleLabel: UILabel = {
        let label = UILabel()
        label.textColor = .label
        return label
    }()

    private lazy var navigationBackButtonImage: UIImage? = {
        return UIImage(systemName: "LeftBackButton")
    }()

    private lazy var backButtonImage: UIImage? = {
        return UIImage(systemName: "chevron.left")
    }()

    private lazy var closeButtonImage: UIImage? = {
        return UIImage(named: "CloseButton")
    }()

    private lazy var towardButtonImage: UIImage? = {
        return UIImage(systemName: "chevron.right")
    }()

    lazy var barBackButtonItem: UIBarButtonItem = {
        // 주의: UIBarButtonItem을 생성할 때 CustomView로 button을 넣을경우 하나만 표출되므로 image로 넣어서 사용
        return UIBarButtonItem(image: backButtonImage, style: .plain, target: self, action: #selector(didTapToolBarBackButton))
    }()

    lazy var barTowardButtonItem: UIBarButtonItem = {
        // 주의: UIBarButtonItem을 생성할 때 CustomView로 button을 넣을경우 하나만 표출되므로 image로 넣어서 사용
        return UIBarButtonItem(image: towardButtonImage, style: .plain, target: self, action: #selector(didTapToolBarTowardButton))
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        if navigationController?.viewControllers.first == self {
            navigationItem.leftBarButtonItem = UIBarButtonItem(customView: closeButton)
        } else {
            navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)
        }
    }

    @objc func didTapBackButton() {
        navigationController?.popViewController(animated: true)
    }

    @objc func didTapCloseButton() {
        dismiss(animated: true, completion: nil)
    }

    func showBackButton(isHide: Bool) {
        backButton.isHidden = isHide
        closeButton.isHidden = isHide
    }

    // MARK: - UIToolBar

    func addBottomToolBar() {
        let paddingButtonItem = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
        paddingButtonItem.width = 24.0
        toolbarItems = [barBackButtonItem, paddingButtonItem, barTowardButtonItem]
        navigationController?.isToolbarHidden = false
    }

    @objc func didTapToolBarBackButton() {
        // override this method
    }

    @objc func didTapToolBarTowardButton() {
        // override this method
    }
}

WebViewController 구현

  • 클래스 생성
class WebViewController: BaseViewController {
}
  • webView 프로퍼티
private lazy var webView: WKWebView = {
    let webview = WKWebView(frame: .zero)
    webview.allowsBackForwardNavigationGestures = true
    webview.navigationDelegate = self
    return webview
}()
  • 생성자 정의
init(url: URL, title: String) {
    self.url = url
    super.init(nibName: nil, bundle: nil)
}
  • BaseViewController에 있는 탭 이벤트 재정의
override func didTapToolBarBackButton() {
    webView.goBack()
}

override func didTapToolBarTowardButton() {
    webView.goForward()
}
  • 뒤로가기, 앞으로가기 버튼 활성화, 비활성화 설정 - NKNavigationDelegate 구현
// 페이지의 화면 전환 이벤트 수신
extension WebViewController: WKNavigationDelegate {
    /// WKWebView에서 다른곳으로 이동할때마다 호출되는 메소드 (didFinish와 짝꿍)
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        print("show loading indicator ...")
        // didFinish에 하지 않고 didCommit에 해야 페이지에 들어가면서 자연스럽게 활성화
        barBackButtonItem.isEnabled = webView.canGoBack
        barTowardButtonItem.isEnabled = webView.canGoForward
    }

    /// WKWebView에서 다른곳으로 이동된 후에 호출되는 메소드 (didCommit와 짝꿍)
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("hide loading indicator ...")
    }
}

* 전체 소스 코드: https://github.com/JK0369/ExWKWebView/tree/ImplementBase

Comments