Objective-C: 点击 Tabbaritem-> 调用方法-> 但 WebView 未刷新

Objective-C: Tabbaritem tapped->Method Called-> But WebView not refreshed

正在努力实现

当我点击 tabbaritem 说 #2 时,它会调用该方法并重新加载网络视图。

问题

当我点击 tabbaritem 时,该方法被调用,但网页视图没有重新加载。

Did not load the web view

问题

如果我在 VC 本身上调用方法。我可以设法重新加载网络视图。只有当我在点击 tabbaritem 时调用它,它才不会重新加载网络视图。

代码

MyTabBarController.m

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {

    NSLog(@"controller class: %@", NSStringFromClass([viewController class]));
    NSLog(@"controller title: %@", viewController.title);

        if (viewController == [tabBarController.viewControllers objectAtIndex:2])
         {
        [(UINavigationController *)viewController popToRootViewControllerAnimated:YES];
        tabBarController.delegate = self;
         [[[Classes alloc] init] LoadClasses];

    }else if (viewController == [tabBarController.viewControllers objectAtIndex:3]){

        [(UINavigationController *)viewController popToRootViewControllerAnimated:YES];
        tabBarController.moreNavigationController.delegate = self;
        [[[Gym alloc] init] handleRefreshGym:nil];

}else{
        [(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
    }

}

Classes.m

- (void)LoadClasses {

    sURL = @"www.share-fitness.com/apps/class.asp?memCode=SF100012&dtpClass=13/09/2018&lang=EN&lat=37.785835&long=-122.406418&ver=1&plat=IOS"

    NSLog(@"The URL To be loaded %@", sURL);

    NSURL *url = [NSURL URLWithString:sURL];
    sRefresh = sURL;
    [[NSURLCache sharedURLCache] removeAllCachedResponses];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    [webView loadRequest:urlRequest];
    [webView setDelegate:(id<UIWebViewDelegate>)self];

    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    [refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
    [webView.scrollView addSubview:refreshControl];

}

正如我在其他回复 Objective-C: How to properly set didSelectViewController method for TabBarController, so I can refresh the VC everytime it is tapped 中提到的,我认为每次 select 编辑标签栏时从服务器刷新视图并不是好的用户体验(这将让用户每次都等待服务器刷新数据非常烦人)

也就是说,您发布的代码的问题是您正在 TabBarControllerDelegate 方法中初始化 类 的新实例,因此将在这个新实例上调用该方法,而不是在TabBarController 的视图控制器中的 displaying/exists。具体来说,这两行正在初始化新实例:

[[[Classes alloc] init] LoadClasses];
[[[Gym alloc] init] handleRefreshGym:nil];

相反,您应该找到已经存在的实例,然后调用它们的方法。

我建议按照 - (void)doStuffWhenTabBarControllerSelects; 的方式使用 public 方法创建一个 ParentViewController(仅举例命名以明确它对您的作用)然后让每个查看您希望在 select 成为此 parent 的 child 类 时执行某些操作的控制器(并有自己的 - (void)doStuffWhenTabBarControllerSelects; 实现).这样在 TabBarController 的委托方法中,您可以找到 ParentViewController 的适当实例(与正在 selected 的视图控制器相关联)并在其上调用 - (void)doStuffWhenTabBarControllerSelects; 方法。

这是我的意思的一个例子:

ParentViewController.h:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface ParentViewController : UIViewController
- (void)doStuffWhenTabBarControllerSelects;
@end

NS_ASSUME_NONNULL_END

ParentViewController.m:

#import "ParentViewController.h"

@interface ParentViewController ()

@end

@implementation ParentViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)doStuffWhenTabBarControllerSelects {
    NSLog(@"Fallback implementation if this method isn't implemented by the child class");
}

@end

FirstViewController.h:

#import <UIKit/UIKit.h>
#import "ParentViewController.h"

@interface FirstViewController : ParentViewController


@end

FirstViewController.m:

#import "FirstViewController.h"

@interface FirstViewController ()

@end

@implementation FirstViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)doStuffWhenTabBarControllerSelects {
    NSLog(@"I'm doing stuff on the %@ when the tab bar controller delegate calls back to selection", NSStringFromClass([self class]));
}


@end

SecondViewController.h:

#import <UIKit/UIKit.h>
#import "ParentViewController.h"

@interface SecondViewController : ParentViewController


@end

SecondViewController.m:

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)doStuffWhenTabBarControllerSelects {
    NSLog(@"I'm doing stuff on the %@ when the tab bar controller delegate calls back to selection", NSStringFromClass([self class]));
}

@end

MyTabBarController.h:

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyTabBarController : UITabBarController <UITabBarControllerDelegate>

@end

NS_ASSUME_NONNULL_END

MyTabBarController.m:

#import "MyTabBarController.h"
#import "ParentViewController.h"

@implementation MyTabBarController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.delegate = self;
}

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
    // since your view controllers are embedded in nav controllers, let's make sure we're getting a nav controller
    if ([viewController isKindOfClass:[UINavigationController class]]) {
        // we're expecting a nav controller so cast it to a nav here
        UINavigationController *navController = (UINavigationController *)viewController;
        // now grab the first view controller from that nav controller
        UIViewController *firstViewControllerInNav = navController.viewControllers.firstObject;
        // check to make sure it's what we're expecting (ParentViewController)
        if ([firstViewControllerInNav isKindOfClass:[ParentViewController class]]) {
            // cast it to our parent view controller class
            ParentViewController *viewControllerToCallMethodOnAfterSelection = (ParentViewController *)firstViewControllerInNav;
            [viewControllerToCallMethodOnAfterSelection doStuffWhenTabBarControllerSelects];
        }
    }
}

@end

然后当您在两个选项卡之间 select 时,您将得到以下输出:

I'm doing stuff on the FirstViewController when the tab bar controller delegate calls back to selection

I'm doing stuff on the SecondViewController when the tab bar controller delegate calls back to selection

我建议做一些额外的 research/reading 文档:

这里有大量初学者信息:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/DefiningClasses/DefiningClasses.html#//apple_ref/doc/uid/TP40011210-CH3-SW1

UITabBar控制器:https://developer.apple.com/documentation/uikit/uitabbarcontroller?language=objc

UITabBarControllerDelegate: https://developer.apple.com/documentation/uikit/uitabbarcontrollerdelegate?language=objc

另一个有用的提示是,在 Xcode 中,您可以按住选项键并单击某些内容以快速查看 explanation/documentation

您也可以右键单击某些内容然后 "Jump To Definition"。大多数 Apple 的实施将在 header.

中提供附加信息

这是 UITabBarController header 中的示例:

/*!
 UITabBarController manages a button bar and transition view, for an application with multiple top-level modes.

 To use in your application, add its view to the view hierarchy, then add top-level view controllers in order.
 Most clients will not need to subclass UITabBarController.

 If more than five view controllers are added to a tab bar controller, only the first four will display.
 The rest will be accessible under an automatically generated More item.

 UITabBarController is rotatable if all of its view controllers are rotatable.
 */

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBarController : UIViewController <UITabBarDelegate, NSCoding>

在帮助菜单下还有 "Developer Documentation" (CMD + SHIFT + 0),其中包含大量有用的信息。