【问题标题】:Objective-C WKWebView: didFinish not triggering when WebView finishes loadingObjective-C WKWebView:当 WebView 完成加载时 didFinish 不触发
【发布时间】:2022-12-13 07:50:02
【问题描述】:

我的应用程序是 Objective-C,我正在一点一点地迁移,所以我需要 Objective-C 的帮助,而不是 Swift。

我正在将 UIWebView 迁移到 WKWebView 并且在使 didFinish 工作时遇到问题。

这是我使用 WebView、TMAnswerView 的类:

#import "TMAnswerView.h"
#import "TMConsts.h"
#import "TMPersistanceManager.h"
#import <WebKit/WebKit.h>

@interface TMAnswerView () <WKNavigationDelegate>
//UIWebViewDelegate
@end

@implementation TMAnswerView.m

-(void)customInit{
        
}

-(void)setAnswer:(TMAnswerModel *)answer{
    
    _answer = answer;
    
    float font = 17;
    NSNumber *type = [TMPersistanceManager fetchObjectForKey:PERSettingsFontSize];
    if([type isEqual:SettingsFontSizeType1]){
        font = font * 0.75;
    }else if([type isEqual:SettingsFontSizeType3]){
        font = font * 1.25;
    }else if([type isEqual:SettingsFontSizeType4]){
        font = font * 1.5;
    }else if([type isEqual:SettingsFontSizeType5]){
        font = font * 2;
    }
    
    NSString *htmlBody = [TMUtils getHTMLStringForMath:[answer.answer stringByReplacingOccurrencesOfString:@"$$" withString:@"$"] andFontSize:(int)font];
    
    [_answerWebView loadHTMLString:htmlBody baseURL:[NSURL fileURLWithPath: [NSString stringWithFormat:@"%@/", [[NSBundle mainBundle] bundlePath]]]];
    _answerWebView.scrollView.contentInset = UIEdgeInsetsMake(0,-8,0,-8);
    
}

#pragma mark - click listeners

- (IBAction)onCheckButton:(id)sender {
    if(_viewControllerType != TMMainTestViewConstrollerTypeDoTest){
        return;
    }
    _checkButton.selected = !_checkButton.selected;
    if(_delegate){
        [_delegate onCheckChanged:_answer];
    }
}

- (void)webView:(WKWebView *)webView
didFinishNavigation:(WKNavigation *)navigation{
    [self setWebViewHeight];
}

//-(void)webViewDidFinishLoad:(WKWebView *)webView{
//    [self setWebViewHeight];
//}

-(void) setWebViewHeight{
    CGSize fittingSize = [_answerWebView sizeThatFits:CGSizeZero];
    _heightOfWebView.constant = fittingSize.height;
}

@end

在这里,我用 WKNavigationDelegate 替换了 UIWebView 委托。我不得不提的是,它与 UIWebView 的旧 webViewDidFinishLoad 一起工作正常。

TMAnswerView.h:

#import "TMCustomView.h"
#import "TMAnswerModel.h"
#import "TMMainTestViewController.h"
#import <WebKit/WebKit.h>

@protocol TMAnswerViewProtocol <NSObject>

-(void) onCheckChanged:(TMAnswerModel*) answer;

@end

@interface TMAnswerView : TMCustomView

@property (nonatomic, strong) TMAnswerModel *answer;

@property (weak, nonatomic) IBOutlet UIButton *checkButton;
@property (weak, nonatomic) IBOutlet WKWebView *answerWebView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightOfWebView;

@property (weak, nonatomic) id<TMAnswerViewProtocol> delegate;

@property (nonatomic) TMMainTestViewConstrollerType viewControllerType;
-(void) setWebViewHeight;

@end

最后在情节提要中,我添加了一个 WebKitView 元素来替换旧的 UIWebView。

我也试过 didFinishNavigation 无济于事。

我检查了下一页作为参考:

WKWebView

我的代码有什么问题吗?如何触发 didFinish 事件?

编辑 1

我也试过:

- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
    [self setWebViewHeight];
}

无济于事。

编辑 2

这是加载 WKWebView 的类,TMQuestionView:

#import "TMQuestionView.h"
#import "TMColors.h"
#import "TMDBManager.h"
#import "TMConsts.h"
#import "TMAnswerModel.h"
#import "TMAnswerView.h"
#import "TMViewUtils.h"
#import "TMPersistanceManager.h"
#import "TMImagePreviewView.h"
#import <WebKit/WebKit.h>

@interface TMQuestionView () <TMAnswerViewProtocol, WKNavigationDelegate>

@property (weak, nonatomic) IBOutlet WKWebView *webView;
@property (weak, nonatomic) IBOutlet UIView *answersView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *webviewHeight;
@property (weak, nonatomic) IBOutlet UIView *viewForLoading;
@property (weak, nonatomic) IBOutlet UIView *loadingView;
@property (weak, nonatomic) IBOutlet WKWebView *webviewExplanations;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *webviewExplanationsHeight;

@property (nonatomic) BOOL isExplanationsVisible;

@property (nonatomic, strong) NSMutableArray *images;

@property (nonatomic, strong) NSString *tempic;

@end

@implementation TMQuestionView

-(void)customInit{
    
    [[CSLoadingManager sharedManager] addLoadingViewToView:_viewForLoading withColor:TMBaseColor(1)];
    _images = [NSMutableArray new];
    
}

-(void)setQuestion:(TMQuestionModel *)question{
    _question = question;
    
    float font = 17;
    NSNumber *type = [TMPersistanceManager fetchObjectForKey:PERSettingsFontSize];
    if([type isEqual:SettingsFontSizeType1]){
        font = font * 0.75;
    }else if([type isEqual:SettingsFontSizeType3]){
        font = font * 1.25;
    }else if([type isEqual:SettingsFontSizeType4]){
        font = font * 1.5;
    }else if([type isEqual:SettingsFontSizeType5]){
        font = font * 2;
    }
    
    [_images addObjectsFromArray:[TMUtils getImagesFromQuestion:question.question]];
    [_images addObjectsFromArray:[TMUtils getImagesFromQuestion:question.instructions]];
    
    NSString *htmlString = question.question;
    if(question.instructions.length > 0 && ![question.instructions isEqualToString:@"(null)"]){
        htmlString = [NSString stringWithFormat:@"%@<br/>%@", question.instructions, question.question];
    }
    NSString *htmlBody = [TMUtils getHTMLStringForMath:htmlString andFontSize:(int)font];
    htmlBody = [htmlBody stringByReplacingOccurrencesOfString:@"<center>" withString:@"<p style='text-align:center;'>"];
    htmlBody = [htmlBody stringByReplacingOccurrencesOfString:@"</center>" withString:@"</p>"];

    _tempic = htmlBody;
    
    [_webView loadHTMLString:htmlBody baseURL:[NSURL fileURLWithPath: [NSString stringWithFormat:@"%@/", [[NSBundle mainBundle] bundlePath]]]];
    _webView.scrollView.contentInset = UIEdgeInsetsMake(0,-8,0,-8);
    _answersView.hidden = YES;
    
    [[TMDBManager sharedManager] getAnswersForQuestion:_question completition:^(NSDictionary *dict) {
        
        NSArray *temp = [dict objectForKey:DBReturnAnswers];
        NSSortDescriptor *sortDescriptor;
        sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"answerNumber" ascending:YES];
        NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
        self->_answers = [temp sortedArrayUsingDescriptors:sortDescriptors];

        [self setViewAnswers];
    }];
    
}

-(void) setExplanations{
    _isExplanationsVisible = YES;
    float font = 17;
    NSNumber *type = [TMPersistanceManager fetchObjectForKey:PERSettingsFontSize];
    if([type isEqual:SettingsFontSizeType1]){
        font = font * 0.75;
    }else if([type isEqual:SettingsFontSizeType3]){
        font = font * 1.25;
    }else if([type isEqual:SettingsFontSizeType4]){
        font = font * 1.5;
    }else if([type isEqual:SettingsFontSizeType5]){
        font = font * 2;
    }
    NSString *htmlString = _question.explanation;
    NSString *htmlBody = [TMUtils getHTMLStringForMath:htmlString andFontSize:(int)font];
    [_webviewExplanations loadHTMLString:htmlBody baseURL:[NSURL fileURLWithPath: [NSString stringWithFormat:@"%@/", [[NSBundle mainBundle] bundlePath]]]];
    _webviewExplanations.scrollView.contentInset = UIEdgeInsetsMake(0,-8,0,-8);
}

-(void)setRecordAnswer:(TMRecordAnswerModel *)recordAnswer{
    _recordAnswer = recordAnswer;
}

-(void) setViewAnswers{
    int i = 0;
    
    float font = 17;
    NSNumber *type = [TMPersistanceManager fetchObjectForKey:PERSettingsFontSize];
    if([type isEqual:SettingsFontSizeType1]){
        font = font * 0.75;
    }else if([type isEqual:SettingsFontSizeType3]){
        font = font * 1.25;
    }else if([type isEqual:SettingsFontSizeType4]){
        font = font * 1.5;
    }else if([type isEqual:SettingsFontSizeType5]){
        font = font * 2;
    }
    
    for(TMAnswerModel *item in _answers){
        
        TMAnswerView *view = [[TMAnswerView alloc] init];
        view.translatesAutoresizingMaskIntoConstraints = NO;
        [_answersView addSubview:view];
        [[view.leadingAnchor constraintEqualToAnchor:_answersView.leadingAnchor constant:0] setActive:YES];
        [[view.rightAnchor constraintEqualToAnchor:_answersView.rightAnchor constant:0] setActive:YES];
        if(i == 0){
            [[view.topAnchor constraintEqualToAnchor:_answersView.topAnchor constant:0] setActive:YES];
        }else{
            UIView *lastView = [[_answersView subviews] objectAtIndex:i-1];
            [[view.topAnchor constraintEqualToAnchor:lastView.bottomAnchor constant:0] setActive:YES];
        }

        view.answer = item;
        view.delegate = self;
        view.viewControllerType = _viewControllerType;
                
        if(_recordAnswer){
            if(item.isCorrect == 1){
                if([_recordAnswer.selectedAnswerId isEqualToString:item.answerId]){
                    [view.checkButton setImage:[UIImage imageNamed:@"checkbox_checked"] forState:UIControlStateNormal];
                }else{
                    [view.checkButton setImage:[UIImage imageNamed:@"checkbox_checked_gray"] forState:UIControlStateNormal];
                }
            }else{
                if([_recordAnswer.selectedAnswerId isEqualToString:item.answerId]){
                    [view.checkButton setImage:[UIImage imageNamed:@"checkbox_error"] forState:UIControlStateNormal];
                }
            }
        }


        i++;
        
        if(i == [_answers count]){
            [[view.bottomAnchor constraintEqualToAnchor:_answersView.bottomAnchor constant:0] setActive:YES];
        }
    }
}

-(void)onCheckChanged:(TMAnswerModel *)answer{
    for (TMAnswerView *item in [_answersView subviews]){
        if(![item.answer isEqual:answer]){
            if(item.checkButton.selected){
                item.checkButton.selected = NO;
            }
        }
    }
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
    [self setHeightOfWebView];
}

//-(void)webViewDidFinishLoad:(WKWebView *)webView{
//    [self setHeightOfWebView];
//}

-(TMAnswerModel*) getSelectedAnswer{
    for (TMAnswerView *item in [_answersView subviews]){
        if(item.checkButton.selected){
            return item.answer;
        }
    }
    return nil;
}

-(void) setHeightOfWebView{
    _viewForLoading.hidden = YES;
    _loadingView.hidden = YES;
    CGSize fittingSize = [_webView sizeThatFits:CGSizeZero];
    _webviewHeight.constant = fittingSize.height;
    _answersView.hidden = NO;
    
    for(UIView *item in [_answersView subviews]){
        if([item isKindOfClass:[TMAnswerView class]]){
            [((TMAnswerView*) item) setWebViewHeight];
        }
    }
    
    if(_isExplanationsVisible){
        CGSize fittingSizeExplanations = [_webviewExplanations sizeThatFits:CGSizeZero];
        _webviewExplanationsHeight.constant = fittingSizeExplanations.height;
    }

}

- (IBAction)onButtonAboveWebViewClicked:(id)sender {
    if([_images count] > 0){

        TMImagePreviewView *view = [[TMImagePreviewView alloc] initWithFrame:CGRectMake(0, 0, kAppWidth, kAppHeight)];
        [view setImages:_images];
        [[[self superview] superview] addSubview:view];
        [view fadeIn];
        
    }
}

- (IBAction)onButtonTemp:(id)sender forEvent:(UIEvent *)event {
    NSSet *touches = [event touchesForView:sender];
    UITouch *touch = [touches anyObject];
    CGPoint touchPoint = [touch locationInView:[sender superview]];
    NSLog(@"%@", NSStringFromCGPoint(touchPoint));
    
    
    long htmlLength = _tempic.length;
    
    
    long heightOfWebView = _webView.frame.size.height;
    
    double percentTouch = (double)touchPoint.y / (double)heightOfWebView;
    
    
    int index = 0;
    
    for(NSString *imageStr in _images){
        NSString *match = [[imageStr componentsSeparatedByString:@"/"] objectAtIndex:1];
        NSRange rangeOfImage = [_tempic rangeOfString:match];
        
        double percentText = (double) rangeOfImage.location / (double)htmlLength;

        if(percentText > percentTouch){
            break;
        }
        index++;
        
    }
    
    NSLog(@"STOP");
    
}

@end

【问题讨论】:

  • 您必须使用正确的方法签名才能工作。没有- (void)webView:(WKWebView *)webView didFinish:(WKNavigation *)navigation这样的委托方法。使用正确的名称(请参阅文档),它将起作用。你很接近但不太正确。
  • 这很有趣,因为你没有向我解释如何去做@HangarRash。据推测,如果我问是因为我不知道该怎么做。我确定可能出了什么问题,但不知道是什么。我已经检查过文档,但我是 iOS 开发的新手并且正在尽力而为。你能解释一下怎么做而不是引导我看文档吗?不过还是谢谢你的回复。
  • 我试图给您提示,以便您可以自己查看问题。这是一种更好的学习方式。查看文档。文档中显示的委托方法的全名是什么?将其与您放入代码中的内容进行比较。这是一个很小但很重要的区别。一个字一个字的看,就好像你从来没见过一样。校对自己的作品很困难,因为你总是看到它应该是什么,而不是实际是什么。
  • 这里还有一些建议。 1) 复制文档中的方法并将其粘贴到您的代码旁边,以查看不同之处。 2)使用Xcode的代码补全,让它为你输入签名,避免犯像这样的简单错误。
  • 好的,您最近的编辑现在显示了正确的方法。不是被调用了吗?是否调用了任何其他导航委托方法?你设置导航委托了吗?

标签: ios objective-c xcode uiwebview wkwebview


【解决方案1】:

也许你可以在 TMAnswerView.setAnswer 中添加这个:

-(void)setAnswer:(TMAnswerModel *)answer {
    ...
    // set self as navigationDelegate for the webView
    _answerWebView.navigationDelegate = self;
    
    [_answerWebView loadHTMLString:htmlBody...
... 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    相关资源
    最近更新 更多