티스토리 뷰

반응형

 

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

제곧내.

 

시작하겠습니다.

 

1.  import WebKit

import WebKit

 

2. webView 변수 만들기

@IBOutlet weak var webView: WKWebView!

저는 스토리보드에서 바로 추가해줘서 IBOutlet으로 만들어줬습니다.

 

3. 로드할 HTML String준비

let str = """
    <script src="https://gist.github.com/Zedd0202/576e378ba44745ff48380ff7fc7d5757.js"></script>
    """

저는 gist를 보여줄거라서..

이렇게 해줬습니다.

 

4. loadHTMLString

네..이렇게나 직관적일수가 ^-^.."Load / HTML / String"

baseURL은 document 내에서 relative URL을 확인하는 데 사용되는 URL이라는데.,,

저는 그냥  nil을 넣어줬습니다!! 이 친구의 정확한 역할이 뭔지 모르겠어요..

 

5. 빌드.

이런식으로 나오게 됩니다!!! 오른쪽 사진은...그냥 아무 HTML String넣어본거임. 

 

# 개선

자...지금 상태는 왼쪽처럼 되어있는데요,

오른쪽 처럼 WebView에 height constraint를 줘보겠습니다. 

Q : webView content의 높이를 구한 뒤, height constraint를 업데이트 시켜주면 좋을텐데!

해보겠습니다.

 

1. WKNavigationDelegate 채택

class ViewController: UIViewController, WKNavigationDelegate {

 

2. navigationDelegate 대리자 위임

 override func viewDidLoad() {
        super.viewDidLoad()
        self.webView.navigationDelegate = self
 }

 

3. webView load가 끝난시점에 contentSize를 가져오기

코드 출처 : stackoverflow.com/a/53828449

didFinish메소드는 이름에 걸맞게...webView에서 navigation이 끝나면 불리는 메소드인데요, 

이때 저렇게 contentSize를 통해 content의 width와 height을 가져올 수 있습니다.

다만 주의하실 점은, didFinish가 불렸다고 바로 webView content의 size가 바로 결정되는게 아니더라구요.

그래서 asyncAfter메소드를 이용해줬습니다. 다만 위 코드는 0.1초 내에 content의 높이가 결정되었을 때만 작동하는 코드에요.

위 메소드는 webView의 모든 컨텐츠가 다 떴어!! 가 아니라

webView가 그냥 navigation이 끝나면 불리는 코드입니다. 

해당 사이트로 가긴갔어! -> didFinish불림.

근데 리소스가 뭐 너무 크던지 해서 걔네 로딩이 걸릴 수 있는거잖아요?

걔네가 로딩이 되기전까지는 content의 size가 얼마나 될지 모르는거죠. 

그래서 상황에 맞게...사용 해주세요. 모든 content가 다 로딩이 되었다!! 라는 Delegate메소드는 없습니다 ㅠㅠ..

아무튼 이렇게 하면,

이런식으로 content높이와 같게 webView높이를 줄 수 있습니다.

마지막 사진은 웹뷰가 스크롤뷰 위에 그려지다 보니...저렇게 스크롤이 되는 것을 볼 수 있습니다. 

뭐 저는 content에 맞게 딱!! 높이를 준 상태이기 때문에...(HTML String이기도 하고...)

스크롤을 막아주겠습니다.

지금 생각하고계신 "그 코드"로 해결하면 됩니다. 

 

# WebView 스크롤 막기

self.webView.scrollView.isScrollEnabled = false

간-단

 

# 개선2

저는

let str = """
    <script src="https://gist.github.com/Zedd0202/576e378ba44745ff48380ff7fc7d5757.js"></script>
    """

이런 코드인데요, 만약 유효하지 않은 gist면 어떻게 해야할까요?

저 Zedd0202뒤에있는 주소를 막 몇개 지운뒤 빌드해보겠습니다.

이렇게 나오지 않게 됩니다!

당연히 유효하지 않은 주소기때문에...그렇습니다. 이를 어떻게 판별해야할까요? 

URL을 사용하여 webView를 로드했는데 -> 유효하지 않을 경우? -> decidePolicyFor 메소드를 이용하여 statusCode를 얻어내면 됩니다. 하지만 지금은 LoadHTMLString이기 때문에 decidePolicyFor메소드가 불리지 않습니다. 

판별하는 방법은....뭐 제각각 일 수 있을 것 같은데..저는

didFinish에서 evaluateJavaScript를 해주겠습니다. 

저렇게하면 유효한 gist같은 경우에는

<html><head><script src="https://gist.github.com/Zedd0202/576e378ba44745ff48380ff7fc7d5757.js"></script><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-fd43f22140a6ad2cc9d0aa1f169a01f3.css"></head><body><div id="gist105454793" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-fetchassets-swift" class="file my-2">
    

  <div itemprop="text" class="Box-body p-0 blob-wrapper data type-swift  ">
      
 .......(중략)

  </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Zedd0202/576e378ba44745ff48380ff7fc7d5757/raw/157755543ea876f873d4dc973cd120a2d2107721/fetchAssets.swift" style="float:right">view raw</a>
        <a href="https://gist.github.com/Zedd0202/576e378ba44745ff48380ff7fc7d5757#file-fetchassets-swift">fetchAssets.swift</a>
        hosted with ❤ by <a href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</body></html>

 

이러한 HTML String이 나오게 됩니다. 

만약 유효하지 않은 주소면

<html><head><script src="https://gist.github.com/Zedd0202/576e378ba44745380ff7fc7d5757.js"></script></head><body></body></html>

그냥 이렇게 나오게 됩니다. 

그래서....

이렇게 해줬는데....너무 위험한 코드일까요?! 

근데 LoadHTMLString같은 경우에는...이런식으로 밖에 할 수 없지 않나!? 하는 생각도 들기도 하고,,,

 

반응형