티스토리 뷰

안녕하세요 :) Zedd입니다.

제가 앱에서 발견한 치명적인 버그가 있는데..이걸 왜 이제야 찾았는지 ㅠㅠㅠ 

바로 WKWebView에 뒤로가기 버튼이 없다는 사실

그래서 오늘은 WKWebView에 뒤로가기 버튼을 만들어보겠습니다.

제가 모티브..?로 할 것은




카카오톡에서 제 블로그를 열면 저렇게 밑에 뒤로가기 앞으로가기, 공유버튼이 있어요.

아무튼...만들어봅시다. 



WKWebView에 Back Button만들기




일단...이렇게 만들어주었습니다. 아이콘은 나중에 넣는 걸로

아!! 찾아보니 Delegate메소드로 다 있는 것 같네요 :) 그렇게 어려운 여정이 될 것 같지는 않습니다..

엄청 쉬운거였네요...

아무튼 일단 딱 처음 들어갔을 때는 뒤로 앞으로가 없으니 화살표 버튼을 비활성화 시켜주겠습니당.



그럼 이제 어떻게 하느냐!!!

바로 WKWebView의 메소드를 사용하면 됩니다.




이름만 봐도 감이오죠

뒤로갈 수 있느냐?

앞으로 갈 수 있느냐?


canGoBack의 정의는 

"탐색할 수 있는 역방향 목록( back-forward list )에 역방향 항목이 있는지 여부를 나타내는 Bool값입니다"


canGoForward의 정의는 

"탐색할 수 있는 항목에 역방향 목록( back-forward list )에 있는지 여부를 나타내는 Bool값입니다"

(저는 처음에 아니 앞으로 갈 수 있는데 왜 역방향 목록이야;;;했는데..뒤로 갈 수 있는 list따로, 앞으로 갈 수 있는 list를 따로 만들어놓는 게 아니라, back-forward list를 둘다 쓰는 것 같아요. 앞으로 갈 수 있다는 것은, 제가 이미 한번 방문한 곳이라는 것을 의미하니까요. 제 생각인데..혹시 아니라면 지적 부탁드립니다 :) canGoForward가 back-forward list를 사용하는 건 맞아요 XD ) 


그럼 내가 해야 할 일


1. 만약 canGoBack/canGoForward가 true 면 버튼을 비활성화 -> 활성화 시켜주고 해당 버튼을 누르면 뒤로가기 / 앞으로 가기가 된다.

2. 만약 canGoBack/canGoForward가 false면 버튼을 활성화 -> 비활성화.


근데!! 딱 직면한 문제점


지금 상태는 두 버튼 모두 비활성화 상태인데? -> 이 버튼들의 Action은 활성화상태일때만 불리지? -> 그럼 어디서 이 버튼들을 활성화 시켜주지?


입니다. 그래서 또 Delegate메소드를 찾아봄 ㅎㅎ

WKWebView의 Delegate메소드 정리는 < WKWebView에서 loading indicator처리 >에 해놨으니 참고하세요!

일단 제가 한 뎁스씩을 들어가는지 확인시켜주는 메소드가 필요한거죠?

그건.. 



  1. func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!){

    }


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

    }



위 메소드에서 모두 가능하답니다.

제가 간과한 사실이.. 처음 WKWebView가 만들어질때? 그러니까 내가 버튼버튼 클릭으로 들어가는? 그런 것들을 모두 포함해서 didCommit과 didFinish가 불리는 줄 알았어요. 그러니까 딱 한번씩만 불리는 줄 알았다는 이야기.

그런데, WKWebView상에서 다른곳으로 이동할 때마다 위 메소드들이 불리더라구요. :)

그럼 저기 위에서 버튼들을 활성화 시켜주면 되겠죠? 

저는 didFinish에서 해줄게요.


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

            backButton.isEnabled = webView.canGoBack

            forwardButton.isEnabled = webView.canGoForward

    }



저는 이렇게 했어요! 갈 수 있으면 해당 버튼들을 활성화하고, 갈 수 없으면 다시 비활성화 ~.~ 

if - else로 하는 것보다 훨씬 간결하죠?

그럼 이제 뒤/앞으로 갈 수 있으면 버튼들이 활성화 됐고..그 버튼들을 눌렀을 때 진짜 뒤/앞으로 가야겠죠? 


  1. @IBAction func backButtonAction(_ sender: Any) {

            webView.goBack()

            webView.reload()

        }


    @IBAction func forwardButtonAction(_ sender: Any) {

            webView.goForward()

            webView.reload()


        }


이것도 따로 뭐 구현할 필요없이 WKWebView에..다 구현이 되어있습니다..이렇게 쉬운거였다니

goBack()과 goForward()의 이름에서 뭘 해줄지 다 감이 오시죠?

goBack()은  back-forward list에 있는 전에 있는 항목으로 이동하게 해주는 메소드입니다. 만약  back-forward list이 비어있다면 nil을 반환합니다.

goForward()도 마찬가지! back-forward list에서 앞에있는 항목으로 이동하게 해주는 메소드에요. 역시나 back-forward list이 비어있다면 nil을 반환해요.


webView.reload()는 반드시 해줘야 한다고 합니다 :)

오 구현 그래도 일찍 끝났네..하는 도중에 

이 메소드 발견

이름에서 볼 수 있듯이 Gesture로 뒤로가기/앞으로가기 탐색을 허락해주는 프로퍼티입니다. 기본값은 false에요.

true로 하면? -> Gesture로 뒤로가기/앞으로 가기 가능ㅇㅇ

ㅋㅎ....이걸 이제 발견하다니 




정말 Gesture로 뒤로가기 /  앞으로가기가 되죠? 

근데......이게 잘되긴 되는데..Xcode Consol창에는 



이게 뜹니다...근데 뒤로가기 앞으로가기는 진짜 잘되는데.......이게 떠요 그냥..뭐지..? 이게 


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

        print(error.localizedDescription)

    }


여기서 나오는 에러인데...이 에러가 뜨면 didFinish가 안불립니다 ㅠㅠ...

이 에러를 찾아봐도 왜 뜨는 에러인지 안나오더라구요..

그래서 일단 Gesture는 빼고 버튼으로만 하기로 결정


최종본! 지금 한 뎁스 들어온거니 뒤로가기 버튼이 활성화 된 것 보이시죠?

이건 기능추가인지..버그수정인지...헷갈리네요...

WKWebView상에서 뒤로가기 / 앞으로가기가 되지 않던 버그를 수정한것이니 그냥 Patch버전을 올려야할듯하면서도 뭔가 기능추가라 Minor버전을 올려야할 것만 같은......

아무튼 오늘도 도움이 되었길 바랍니다 :)


+ ) 이렇게 안하고 그냥  SFSafariViewController로 보여주면 다 됩니ㄷㅏ......

뒤로가기, 앞으로가기, 공유, 사파리로 열기 다 됨


댓글
  • 프로필사진 햄드 매번 좋은 글 감사합니다. 한가지 궁금한 점이 있는데요. 현재 WKWebView를 전체화면에 띄워서 웹상에서 회원가입을 하도록 했습니다. 그리고 회원가입 버튼(웹 버튼)을 누르면 회원가입이 완료되고 이전 뷰(네이티브)로 빠지게 하고싶은데... 도통 어떻게 구현을 해야할지 모르겠네요. 방법 아신다면 답변 주시면 감사하겠습니다. 2019.03.12 17:00
  • 프로필사진 Favicon of https://zeddios.tistory.com BlogIcon Zedd0202 음 잘 모르겠는데..회원가입이 완료된 그 유저의 쿠키를 받아와서 그 쿠키로 로그인을 한 다음, 화면을 업데이트 치면 될 것 같은데..확실하진 않아요! 2019.03.12 19:14 신고
  • 프로필사진 letzdev ios최신 버전에서는 reload사용하면 안되네요.. 2019.07.22 17:18
  • 프로필사진 Favicon of https://zeddios.tistory.com BlogIcon Zedd0202 12.4말씀하시는건가요? 왜 안되나용? 설명해주시면 감사하겠습니다 2019.07.22 18:50 신고
  • 프로필사진 Favicon of https://archijude.tistory.com BlogIcon Jude_Song -_-;
    self.webview.goback() 다음에 reload()하면 올바르게 작동안합니다...

    goback()에서 뒤로가기 페이지 로딩중에 reload()해버려서 작동이 안되는것 같네요.
    빼니깐 올바르게 작동되네요..
    2020.03.11 18:45 신고
댓글쓰기 폼
Total
3,260,860
Today
489
Yesterday
1,782