인터페이스 빌더의 WKWebView


95

XCode 6 베타의 IB 개체 템플릿은 여전히 ​​이전 스타일 개체 (iOS 용 UIWebView 및 OSX 용 WebView)를 만들고있는 것 같습니다. 바라건대 Apple은 최신 WebKit에 맞게 업데이트 할 것이지만 그때까지 Interface Builder에서 WKWebView를 만드는 가장 좋은 방법은 무엇입니까? 기본보기 (UIView 또는 NSView)를 생성하고 WKWebView에 해당 유형을 할당해야합니까? 온라인에서 찾은 대부분의 예제는 프로그래밍 방식으로 컨테이너 뷰에 추가합니다. 어떤 이유로 더 나은가요?


3
이것은 여전히 ​​열려있는 버그입니다 : lists.webkit.org/pipermail/webkit-unassigned/2014-September/…
David H

4
Xcode 7.2를 사용하고 있는데 개체 라이브러리에 WKWebView가 표시되지 않습니다. 여전히 사용할 수 없습니까?
user3731622

10
Xcode 8에는 아직 없습니다.
Ryan Ballantyne

1
Xcode 9.0.1은 이제 IB에서 WKWebView를 지원합니다. 여기에있는 모든 답변은 이제 더 이상 사용되지 않습니다.
smileBot

1
@smileBot 새 버전의 Xcode에는 WKWebView가 있지만 iOS 11 이상을 대상으로해야합니다. crx_au 답변이 가장 잘 작동합니다-> stackoverflow.com/a/40118654/757503
mikemike396

답변:


70

맞습니다-작동하지 않는 것 같습니다. 헤더를 보면 다음이 표시됩니다.

- (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;

이는 펜촉에서 인스턴스화 할 수 없음을 의미합니다.

viewDidLoad 또는 loadView에서 수동으로해야합니다.


바라건대 그들은 언젠가는 그것을 바꿀 것이지만 큰 문제는 아니라고 생각합니다. Johan은 저에게 WWDC 비디오를 다시 지적했으며 심지어 그들은 코드에서 인스턴스화하고 있습니다.
Adam Fox

3
플러스 측면에서 코드로 수행하면 iOS 7에서는 UIWebView를, iOS 8에서는 WKWebView를 사용할 수 있습니다.
EricS

이 답변 후에는 WKWebView의 하위 클래스 에서이 메서드를 재정의 한 다음 인터페이스 작성기에서 사용할 수 있다고 생각합니다 .. 그러나 super.initWithCoder .. 테스트 해 봅시다! :)
zarghol 2015 년

1
개인 시험 후 : 당신은 ... 너무 나쁜 ... "사용할 수없는 표시되었습니다 '초기화'를 재정의 할 수 없습니다"수 없습니다
zarghol

2
한 가지 합리적인 방법은 WKWebView 또는 UIWebView를 하위 뷰로 포함하는 MyWebView라는 UIView 하위 뷰를 만드는 것입니다.이 하위 뷰는 런타임에 initWithCoder에서 결정됩니다. 그런 다음 IB에서 MyWebView보기를 만들 수 있습니다. Swift를 사용하는 경우 IBInspectable 키워드를 사용하여 IB에서 편집 할 수있는 속성을 추가 할 수도 있습니다.
EricS

65

일부 사람들이 지적했듯이 Xcode 6.4부터 WKWebView는 Interface Builder에서 여전히 사용할 수 없습니다. 그러나 코드를 통해 추가하는 것은 매우 쉽습니다.

내 ViewController에서 이것을 사용하고 있습니다. 인터페이스 빌더 건너 뛰기

import UIKit
import WebKit

class ViewController: UIViewController {

    private var webView: WKWebView?

    override func loadView() {
        webView = WKWebView()

        //If you want to implement the delegate
        //webView?.navigationDelegate = self

        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        if let url = URL(string: "https://google.com") {
            let req = URLRequest(url: url)
            webView?.load(req)
        }
    }
}

13
이 질문은 특히 Interface Builder에 관한 것이므로이 답변은 그다지 도움이되지 않습니다.
Steve Landey 2014-06-19

5
당신이 옳습니다. 나는 "IB에서 WKWebView를 만들 수 없습니다"로 대답을 시작 했어야했습니다.하지만 WWDC의 세션 비디오 "최신 WebKit API 소개"를보고 그들은 Xcode를 사용하고 있습니다. 현재 우리가 사용할 수 있습니다.
Johan

1
비디오를 다시 확인하고 WKWebView를 코드로 인스턴스화하고 있습니다. 비디오에서 17:20 쯤입니다.
Adam Fox

3
무한 루프를 어떻게 생성합니까? 이것은 iOS 문서의 loadView에 대한 설명입니다. "뷰 컨트롤러는 뷰 속성이 요청되었지만 현재는 nil 일 때이 메서드를 호출합니다."
Johan

2
self.view내부 참조loadView() 는 무한 재귀로 이어집니다. 반면에보기를 설정 하는 것은 허용 될뿐만 아니라 실제로 필요합니다 (수동으로 또는에 연결하여super. 그렇지 않으면보기가 인 한 계속 호출됩니다nil).
니콜라스 미아리

29

Info.plist

Info.plist 전송 보안 설정에 추가

 <key>NSAppTransportSecurity</key>
 <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
 </dict>

Xcode 9.1 이상

인터페이스 빌더 사용

개체 라이브러리에서 WKWebView 요소를 찾을 수 있습니다.

여기에 이미지 설명 입력

Swift 5로 프로그래밍 방식으로보기 추가

let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
view.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
webView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
webView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true

Swift 5로 프로그래밍 방식으로보기 추가 (전체 샘플)

import UIKit
import WebKit

class ViewController: UIViewController {

    private weak var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        initWebView()
        webView.loadPage(address: "http://apple.com")
    }

    private func initWebView() {
        let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
        view.addSubview(webView)
        self.webView = webView
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        webView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
        webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
        webView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
    }
}

extension WKWebView {
    func loadPage(address url: URL) { load(URLRequest(url: url)) }
    func loadPage(address urlString: String) {
        guard let url = URL(string: urlString) else { return }
        loadPage(address: url)
    }
}

에 대한 이니셜 라이저에서 새 뷰를 할당하는 것은 좋은 제안이 아닙니다 WebView. crx_au의 반응은 우수
일리아스 카림

나는 작동하는 다른 것을 찾지 못했습니다!! 그래서 ... ILI4S가 좋은 제안이 아닐 수도 있다고 말했듯이, 그것이 있는지 아닌지는 모르겠지만 제대로 작동합니다! 감사합니다 남자, 내 일을 저장! :)
호르헤 코르데로에게

20

Xcode 8을 사용하면 이제 가능하지만이를 달성하는 방법은 아무리 말도 안해도 약간 엉망입니다. 하지만 작동하는 솔루션은 작동하는 솔루션입니다. 설명하겠습니다.

WKWebView의 initWithCoder :는 더 이상 "NS_UNAVAILABLE"로 주석 처리되지 않습니다. 이제 아래와 같이 보입니다.

- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

WKWebView를 서브 클래 싱하여 시작하고 initWithCoder를 재정의합니다. super initWithCoder를 호출하는 대신 initWithFrame : configuration :과 같은 다른 init 메서드를 사용해야합니다. 아래의 빠른 예.

- (instancetype)initWithCoder:(NSCoder *)coder
{
    // An initial frame for initialization must be set, but it will be overridden 
    // below by the autolayout constraints set in interface builder. 
    CGRect frame = [[UIScreen mainScreen] bounds];
    WKWebViewConfiguration *myConfiguration = [WKWebViewConfiguration new];

    // Set any configuration parameters here, e.g.
    // myConfiguration.dataDetectorTypes = WKDataDetectorTypeAll; 

    self = [super initWithFrame:frame configuration:myConfiguration];

    // Apply constraints from interface builder.
    self.translatesAutoresizingMaskIntoConstraints = NO;

    return self;
}

Storyboard에서 UIView를 사용하고 새 하위 클래스의 사용자 정의 클래스를 제공하십시오. 나머지는 평소와 같이 업무입니다 (자동 레이아웃 제약 설정,보기를 컨트롤러의 콘센트에 연결 등).

마지막으로 WKWebView는 UIWebView와 다르게 콘텐츠를 확장합니다. 많은 사람들이 다음의 간단한 조언을 따르기를 원할 것입니다. 점에서 WKWebView가 UIWebView 동작을 더 가깝게 따르기 위해 UIWebView가 수행하는 것과 동일한 배율로 렌더링하도록 콘텐츠 크기 조정에서 WKWebView 억제 입니다.


2
self = [super initWithFrame:myFrame configuration:myConfiguration];제약 조건을 사용하는 경우에도 읽어야 합니다. 설정하는 것을 잊지 마십시오self.translatesAutoresizingMaskIntoConstraints = NO;
Mojo66

메인 화면의 경계를 자리 표시 자 프레임으로 사용하는 대신 CGRectZero를 사용하여 일부 코드를 저장할 수도 있습니다.
Ilias Karim

좋은 솔루션입니다. 잘 작동합니다.
Rayfleck

완벽하게 작동합니다! 스토리 보드에서 WKWebView 제약 조건을 얻기 위해 iOS 11을 대상으로하지 않아도되는 멋진 수정 사항입니다.
mikemike396

20

다음은 crx_au 의 탁월한 답변을 기반으로 한 간단한 Swift 3 버전 입니다.

import WebKit

class WKWebView_IBWrapper: WKWebView {
    required convenience init?(coder: NSCoder) {
        let config = WKWebViewConfiguration()
        //config.suppressesIncrementalRendering = true //any custom config you want to add
        self.init(frame: .zero, configuration: config)
        self.translatesAutoresizingMaskIntoConstraints = false
    }
}

Interface Builder에서 UIView를 만들고 제약 조건을 할당 한 다음 WKWebView_IBWrapper이를 사용자 정의 클래스로 할당합니다 .

유틸리티-> 신원 검사기 탭 [1]


우수 답변
아 므르 호삼

6

최신 버전의 Xcode (예 : v9.2 +)에서이 문제가 계속 발생하면 Webkit을 ViewController로 가져 오면됩니다.

#import <WebKit/WebKit.h>
  1. 수정 전 : 여기에 이미지 설명 입력

  2. 수정 후 :

여기에 이미지 설명 입력


4

이것은 Xcode 9b4에서 분명히 수정되었습니다. 릴리스 노트에는 "WKWebView는 iOS 개체 라이브러리에서 사용할 수 있습니다."라고 나와 있습니다.

iOS 11이 필요한지 또는 아직 이전 버전과 호환되는지 자세히 살펴 보지 않았습니다.


이것이 작동하는지 확인할 수 있습니다! 만세! macOS 스토리 보드에서도 작동합니다 (적어도 macOS 10.13 이상을 대상으로하는 앱의 경우).
Clifton Labrum

1

Xcode 9부터 IB에서 WKWebView를 인스턴스화하고 구성 할 수 있으며 코드에서 수행 할 필요가 없습니다. 여기에 이미지 설명 입력

배포 대상은 iOS 10보다 높아야하며 그렇지 않으면 컴파일 시간 오류가 발생합니다.

여기에 이미지 설명 입력


0

XCode 버전 9.0.1에서 WKWebView는 Interface Builder에서 사용할 수 있습니다.



0

이것이 도움이되는지 확실하지 않지만 대상에 대한 WebKit 프레임 워크를 포함하여 문제를 해결했습니다. 포함하지 말고 참조를 연결하십시오. 나는 여전히 IB에서 WebView 개체를 사용하고 그것을 포함하는 ViewController에 놓았고 문제가 없었습니다 ...

지금까지 4 개의 WKWebView MacOS 프로젝트에서 작업했으며 WebView는 각 프로젝트에서 제대로 작동했습니다.


-14

이것은 Xcode 7.2에서 나를 위해 일했습니다 ...

먼저 스토리 보드 / IB에서 웹보기를 UIWebView 아웃렛으로 추가합니다. 이렇게하면 다음과 같은 속성이 제공됩니다.

@property (weak, nonatomic) IBOutlet UIWebView *webView;

그런 다음 코드를 편집하여 WKWebView로 변경하십시오.

@property (weak, nonatomic) IBOutlet WKWebView *webView;

또한 Identity inspector에서 사용자 정의 클래스를 WKWebView로 변경해야합니다.


나는 이것을 OS X 프로젝트와 함께 시도했다-그것은 작동하지 않는다. 그래서 그것은 iOS의 특별한 경우 임에 틀림 없다.
henrikstroem

2
당신이하는 일은 타입 캐스트와 같습니다. webView의 유형을 전혀 변경할 수 없습니다.
DawnSong
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.