研究1

嵌入WKWebView到UITableViewCell時的空白畫面問題。

一開始就先從WKWebView.mm開始,找出初始化畫面的地方:

- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
{
    if (!(self = [super initWithFrame:frame]))
        return nil;

    [self _initializeWithConfiguration:configuration];

    return self;
}

找到了[self _initializeWithConfiguration:configuration]再往下看裡面的內容:

- (void)_initializeWithConfiguration:(WKWebViewConfiguration *)configuration
{
    ...
#if PLATFORM(IOS)
    CGRect bounds = self.bounds;
    _scrollView = adoptNS([[WKScrollView alloc] initWithFrame:bounds]);
    [_scrollView setInternalDelegate:self];
    [_scrollView setBouncesZoom:YES];

    _avoidsUnsafeArea = YES;
    [self _updateScrollViewInsetAdjustmentBehavior];

    [self addSubview:_scrollView.get()];

    static uint32_t programSDKVersion = dyld_get_program_sdk_version();
    _allowsLinkPreview = programSDKVersion >= firstSDKVersionWithLinkPreviewEnabledByDefault;

    _contentView = adoptNS([[WKContentView alloc] initWithFrame:bounds processPool:processPool configuration:WTFMove(pageConfiguration) webView:self]);

    _page = [_contentView page];
    [self _dispatchSetDeviceOrientation:deviceOrientation()];
    _page->setDrawsBackground(self.opaque);

    [_contentView layer].anchorPoint = CGPointZero;
    [_contentView setFrame:bounds];
    [_scrollView addSubview:_contentView.get()];
    [_scrollView addSubview:[_contentView unscaledView]];
    [self _updateScrollViewBackground];
    _obscuredInsetEdgesAffectedBySafeArea = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeRight;

    _viewportMetaTagWidth = WebCore::ViewportArguments::ValueAuto;
    _initialScaleFactor = 1;
    _fastClickingIsDisabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitFastClickingDisabled"];

    [self _frameOrBoundsChanged];

    ...
#endif
    ...
}

Web頁面的內容應是在WKContentView裡面呈現,而WKContentView又包在WKScrollView裡面,所以本身有頁面滾動的功能,接下來再看其他WKWebView設定畫面的地方:

- (void)setFrame:(CGRect)frame
{
    CGRect oldFrame = self.frame;
    [super setFrame:frame];

    if (!CGSizeEqualToSize(oldFrame.size, frame.size))
        [self _frameOrBoundsChanged];
}

- (void)setBounds:(CGRect)bounds
{
    CGRect oldBounds = self.bounds;
    [super setBounds:bounds];
    [_customContentFixedOverlayView setFrame:self.bounds];

    if (!CGSizeEqualToSize(oldBounds.size, bounds.size))
        [self _frameOrBoundsChanged];
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    [self _frameOrBoundsChanged];
}

發現[self _frameOrBoundsChanged]是WKWebView畫面大小改變會觸發的功能,於是繼續看裡面的情況:

- (void)_frameOrBoundsChanged
{
    CGRect bounds = self.bounds;
    [_scrollView setFrame:bounds];

    if (_dynamicViewportUpdateMode == DynamicViewportUpdateMode::NotResizing) {
        if (!_overridesMinimumLayoutSize)
            [self _dispatchSetMinimumLayoutSize:activeMinimumLayoutSize(self, self.bounds)];
        if (!_overridesMaximumUnobscuredSize)
            [self _dispatchSetMaximumUnobscuredSize:WebCore::FloatSize(bounds.size)];

        BOOL sizeChanged = NO;
        if (auto drawingArea = _page->drawingArea())
            sizeChanged = drawingArea->setSize(WebCore::IntSize(bounds.size), WebCore::IntSize(), WebCore::IntSize());

        if (sizeChanged & [self usesStandardContentView])
            [_contentView setSizeChangedSinceLastVisibleContentRectUpdate:YES];
    }

    [_customContentView web_setMinimumSize:bounds.size];
    [self _scheduleVisibleContentRectUpdate];
}

未完繼續...

results matching ""

    No results matching ""