ios 将视图约束到WKWebView.scollView的底部

67up9zun  于 2023-06-25  发布在  iOS
关注(0)|答案(1)|浏览(106)

我试图在我的WkWebView.scrollView的contentView的底部放置一个视图,但似乎视图总是以原点Y为5000或8000结束,这是WkWebView内部绑定的随机值。
我试着设置框架,但结果是一样的。
我想知道你是否真的可以在webView的contentView结束后放置一个视图,同时仍然使滚动工作?

self.webView.frame = self.view.bounds;
[self.webView.scrollView addSubview:self.myView];
self.myView.translateAutoresizingMaskIntoConstraints = false;
[self.myView.topAnchor constraintEqualToAnchor:self.webView.scrollView.subViews.lastObject.bottomAnchor].active = true;
[self.myView.bottomAnchor constraintEqualToAnchor:self.webView.scrollView.bottomAnchor].active = true;
[self.myView.widthAnchor constraintEqualToAnchor:self.view.widthAnchor].active = true;
rur96b6h

rur96b6h1#

WKWebView不像保存处理过的html的滚动视图那么简单。如果你使用Debug View Hierarchy,你会看到它有多复杂。
我建议:

  • 将“bottomView”添加到Web视图(不是添加到其滚动视图)
  • 将bottomView的底部约束到Web视图框架的底部
  • 实现scrollViewDidScroll并更新.constant以定位bottomView

您需要保持bottomView隐藏直到页面加载,在web视图上设置clipsToBounds,以便bottomView在框架外不可见,并设置web视图的.scrollView.contentInset,以便留出额外的空间来显示bottomView。
下面是一个简单的例子,使用这个页面作为web视图的url:

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@end

ViewController.m

#import <WebKit/WebKit.h>
#import "ViewController.h"

@interface ViewController () <UIScrollViewDelegate, WKNavigationDelegate>
{
    WKWebView *webView;
    UILabel *bottomView;
    NSLayoutConstraint *bottomC;
    CGFloat bottomViewHeight;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    webView = [WKWebView new];

    webView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:webView];

    bottomView = [UILabel new];
    bottomView.text = @"Bottom View";
    bottomView.textAlignment = NSTextAlignmentCenter;
    bottomView.backgroundColor = UIColor.greenColor;

    bottomView.translatesAutoresizingMaskIntoConstraints = NO;
    [webView addSubview:bottomView];
    
    bottomViewHeight = 60.0;
    
    UILayoutGuide *g = self.view.safeAreaLayoutGuide;
    
    [NSLayoutConstraint activateConstraints:@[
        
        [webView.topAnchor constraintEqualToAnchor:g.topAnchor constant:40.0],
        [webView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:8.0],
        [webView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-8.0],
        [webView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:-40.0],
        
        [bottomView.leadingAnchor constraintEqualToAnchor:webView.leadingAnchor constant:0.0],
        [bottomView.trailingAnchor constraintEqualToAnchor:webView.trailingAnchor constant:0.0],
        [bottomView.heightAnchor constraintEqualToConstant:bottomViewHeight],

    ]];
    
    // this will be changed when the webView scrolls
    bottomC = [bottomView.bottomAnchor constraintEqualToAnchor:webView.bottomAnchor constant:0.0];
    bottomC.active = YES;

    // we need to allow the web view to scroll up enough to "add" the bottom view at the bottom
    webView.scrollView.contentInset = UIEdgeInsetsMake(0, 0, bottomViewHeight, 0);

    // delegates
    webView.scrollView.delegate = self;
    webView.navigationDelegate = self;

    // we don't want bottom view showing outside the bounds of the web view
    webView.clipsToBounds = YES;

    // start with bottom view hidden
    bottomView.hidden = YES;
    
    NSURL *url = [[NSURL alloc] initWithString: @"https://stackoverflow.com/questions/76536415/constraints-a-view-to-the-bottom-of-wkwebview-scollview"];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url
                                                  cachePolicy: NSURLRequestUseProtocolCachePolicy
                                              timeoutInterval: 5];
    [webView loadRequest: request];
    
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    // webview has "finished loading"
    bottomC.constant = webView.scrollView.contentSize.height - webView.scrollView.contentOffset.y - webView.frame.size.height + 60.0;
    bottomView.hidden = NO;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    // change the bottomView's bottom constraint constant so it moves with the
    //  bottom of the web view's content
    bottomC.constant = scrollView.contentSize.height - scrollView.contentOffset.y - webView.frame.size.height + 60.0;
}

@end

这将是一个相当高的页面,但一旦你滚动到底部,你会看到绿色标签:

注意:我相信你知道,网页可以是非常动态的,做一些事情,如添加更多的内容,你滚动。因此,这可能是合适的,也可能不是合适的,或者可能需要一些额外的逻辑来处理动态内容。

相关问题