본문 바로가기
iOS, Swift 개발

iOS 웹뷰 with 스토리보드, WkWebview

by Nin J 2024. 4. 25.

오늘은 Webview를 어떻게 만드는지에 대해서 다뤄 보겠다.

Webview는 간단히 말해서 iOS 앱에서 웹페이지를 호출하여 보여 주는 것이다.

항목으로는 UIWebview와 WKWebview가 있는데 UIWebview는 Deprecated 되었고 WKWebview를 사용하고 있다.

단계를 정리하자면

  1. StoryBoard 웹뷰 오브젝트 생성
  2. UIViewController에 WKWebview 관련 항목 상속 및 정의 
  3. 웹페이지 로드 실행 및 로그 이벤트 확인

StoryBoard 웹뷰 오브젝트 생성

StoryBoard 두 가지 종류가 있고 1. UIView 2. Webview 있다.

1. UIView를 그리고 그 위에 Webview를 addSubview 하는 방법 (이미지 1-1) - Constraints : Safe Area 지정을 하여 각각의 디바이스 화면을 지원한다. 또 한  ViewController에 정의한 UiView를 연결해 준다(이미지 1-2)

이미지1-1
이미지1-2

2. 처음부터 스토리 보드 위에 Webview Kit를 그리는 방법 (이미지 2)

이미지2

 

각각의 선택에 따라 진행하면 된다. 여기서는 방법 1) UIView에 addSubview 형식으로 진행하는 방법을 알려 주겠다.

 

UIViewController에 WKWebview 관련 항목 상속 및 정의 

1. 인스턴스 생성 2. 웹페이지 로드 3. addSubview추가 이렇게 되어있는 샘플 소스를 추가했다.

import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

var webView: WKWebView!

    override func viewDidLoad() {

        super.viewDidLoad()

        // WKWebView 인스턴스 생성

        webView = WKWebView(frame: view.bounds)

        webView.navigationDelegate = self

        // 웹 페이지 로드

        if let url = URL(string: "https://www.example.com") {

            let request = URLRequest(url: url)

            webView.load(request)

        }

        // 웹 뷰를 루트 뷰에 추가

        view.addSubview(webView)

}

여기서 추가로 ViewController에서 viewDidLoad 부분에서 1. 인스턴스 생성 2. 웹페이지 로드 3. addSubview 작업이 이루어졌는데 

좀 더 빠르고 정돈된 앱을 하고 싶으면 loadView()를 사용한다.

loadView() 메서드는 UIViewController의 기본 메서드 중 하나로, 뷰 컨트롤러가 자신의 뷰를 로드할 때 호출되는 메서드이다.

loadView() 메서드를 오버라이드하여 사용자 정의한 뷰 계층 구조를 만들거나 로드할 수 있다.

override func loadView() {

        // 뷰를 생성하기 위해 super.loadView()를 호출하지 않고 직접 뷰를 생성합니다.

        let contentController = WKUserContentController()

        let config = WKWebViewConfiguration()

        //config.allowsInlineMediaPlayback = true

      self.adWebView = WKWebView(frame: self.adWebStoryBoard.frame, configuration: config )

      self.adWebView.uiDelegate = self

      self.adWebView.navigationDelegate = self

      self.adWebStoryBoard.addSubview(self.adWebView)

    }

이런 식으로 loadView를 사용하여 인스턴스 생성과 addSubview 작업을 loadView에서 진행하고 viewDidLoad 부분에서 웹페이지 로드를 사용하는 것이 View 측면에서 좀 더 빠르게 보일 수가 있다.

추가적으로 UIView에서 webView를 addSubview 했을 시 화면 이슈가 나온다면 아래의 소스나,

override func viewWillLayoutSubviews() {

        super.viewWillLayoutSubviews()

           self.view.layoutIfNeeded()

        if !self.adWebStoryBoard.frame.equalTo(self.adWebView.frame) {

            self.adWebView.frame = self.adWebStoryBoard.bounds

        }

    }

viewDidLoad에 self.view.layoutIfNeeded()를 사용하면 즉각적으로 UI가 적용이 된다.

* 추가설명(layoutIfNeeded())

layoutIfNeeded() 메서드는 뷰의 레이아웃을 즉시 업데이트하고, 모든 레이아웃 업데이트가 완료될 때까지 대기하는 메서드이다. 이 메서드를 호출하면 시스템은 현재 뷰의 레이아웃을 업데이트하고, 이때 발생하는 모든 레이아웃 관련 연산이 완료될 때까지 기다린다.

일반적으로 뷰의 레이아웃은 자동으로 업데이트되지만, 프로그램적으로 레이아웃을 업데이트해야 할 때가 있다. 이때 layoutIfNeeded() 메서드를 호출하여 즉시 레이아웃을 업데이트할 수 있다. 

 

웹페이지 로드 실행 및 로그 이벤트 확인

우리가 상속 선언하여 받은 WKNavigationDelegate 항목으로 아래 3가지를 선언하면 해당 이벤트를 받을 수 있다.

1. 로드가 시작될 때 호출되는 메서드 2. 로드가 완료될 때 호출되는 메서드 3. 로드 중 에러가 발생했을 때 호출되는 메서드

 // 웹 페이지 로드가 시작될 때 호출되는 메서드

    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {

        // 로딩 인디케이터 표시 등의 작업 수행 가능

    }

 

    // 웹 페이지 로드가 완료될 때 호출되는 메서드

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {

        // 로딩 인디케이터 숨기기 등의 작업 수행 가능

    }

 

    // 웹 페이지 로드 중 에러가 발생했을 때 호출되는 메서드

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {

        // 에러 처리 등의 작업 수행 가능

    }