티스토리 뷰

반응형

안녕하세요 :) 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로 보여주면 다 됩니ㄷㅏ......

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


반응형