UIToolbar
사용자가 탭할 수 있는 UIBarButtonItem객체들의 집합을 보여줍니다.
모든 뷰컨트롤러는 자동으로 toolbarItems배열을 제공합니다.
예제코드
let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let refresh = UIBarButtonItem(barButtonSystemItem: .refresh, target: webView, action: #selector(webView.reload))
toolbarItems = [spacer, refresh]
navigationController?.isToolbarHidden = false
.flexibleSpace
: 공간을 유연하게 사용합니다. 모든 공간이 사용될 때까지 다른 버튼을 한쪽으로 밀어 스프링처럼 작동하는 타입isToolbarHidden
: false로 한다면, 툴바를 보여주고 현재뷰에서 로드하게 됩니다.UIProgressView
작업이 진행률(진행되는 정도)를 나타내는 컬러 막대형식으로 보여줍니다.
WKWebView.estimatedProgress을 사용하면 페이지가 얼만큼 로드되었는지를 알 수 있습니다.
estimatedProgress의 값은 기본값 0 ~ 1 까지 숫자입니다.
WKNavigationDelegate는 값이변경될 때를 알 수 없기 때문에 key-value observing을 통해 호출합니다.
progressView = UIProgressView(progressViewStyle: .default)
progressView.sizeToFit()
let progressButton = UIBarButtonItem(customView: progressView)
sizeToFit()
: progressView가 컨텐츠에 완전히 맞도록 레이아웃 크기를 설정하도록 지시합니다.UIBarButtonItem
을 사용해야 하기 때문에 customView파라미터로 UIView를 추가합니다.Key-Value Observing
'누구나 언제든지 객체 Y의 속성 X가 변경되면 알려주세요'라고 말할 수 있습니다.
webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)
estimatedProgress
의 키값을 추적합니다.
addObserver()
관찰자가 누구인지 (관찰자이므로 self사용)
관찰하려는 속성 (WKWebView.estimatedProgress)
forProperty
: 경로지정가능 , forKeyPath
원하는 값 (방금 설정된 값을 원함, 새로운 것 .new)
컨텍스트 값
고유 한 값을 제공하면 값이 변경되었다는 알림을받을 때 동일한 컨텍스트 값이 다시 전송됩니다.
이를 통해 컨텍스트를 확인하여 호출 된 관찰자가 있는지 확인할 수 있습니다. 버그를 피하기 위해 컨텍스트를 지정(및 확인)해야하는 경우가 있을 수 있습니다.
관찰자 등록 후, 관찰 된 값이 변경된시기를 알려줍니다.
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "estimatedProgress" {
progressView.progress = Float(webView.estimatedProgress)
}
}
⚠️ 복잡한 프로그램에서는 관찰을 마쳤을 때 (예: 뷰컨트롤러 사용이 끝났을 때)에 호출한 addObserver()만큼 removeObserver()를 해서 관찰자를 제거해줍니다.
모든 링크를 확인하여 안전한지 확인하는 기능 추가 - 없는 웹사이트 접근하는 것을 방지하기 위해
WKNavigationDelegate의 메서드
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
let url = navigationAction.request.url
if let host = url?.host {
for website in websites {
if host.contains(website) {
decisionHandler(.allow)
return
}
}
}
decisionHandler(.cancel)
}
url?.host
: URL에 대한 호스트(예: apple.com과 같은 웹사이트 도메인)가 있는지 확인decidePolicyFor
: 이 델리게이트 메서드를 사용하면 어떤일이 발생할 때마다 탐색을 허용할지의 여부를 결정할 수 있습니다. 페이지의 어느 부분이 탐색을 시작했는지 확인할 수 있고, 링크를 클릭하거나 양식을 제출하여 트리거되었는지 여부를 확인할 수 있으며,이 경우 URL을 확인하여 마음에 드는지 확인할 수 있습니다.decisionHandler
: 페이지를 로드할 지 여부를 정합니다. 이것은 실제로 함수를 보유하고 있습니다. 즉, 매개 변수를 "호출"하면 실제로 함수를 호출하는 것입니다.contains() 와 hasPrefix()
contains()
: 확인할 문자열을 제공하고 사용한 문자열 내에서 발견하면 true 반환
hasPrefix()
: 문자열이 지정된 접두어로 시작하는지 여부를 나타내는 지 확인
https://developer.apple.com/documentation/swift/string/1540100-hasprefix