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

走远了吗. 提交于 2020-01-06 05:22:26

问题


Trying to achieve

When I tap on the tabbaritem say #2, it will called the method and reload the web view.

Issue

When I tap on the tabbaritem, the method is called but web view did not reload.

Did not load the web view

Question

If I called the method on the VC itself. I can manage to reload the web view. Only if I called it when the tabbaritem is tapped, it doesn't reload the web view.

Code

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];

}

回答1:


As I mentioned in my other reply Objective-C: How to properly set didSelectViewController method for TabBarController, so I can refresh the VC everytime it is tapped, I don't think it's good User Experience to be refreshing the view from the server every time the tab bar is selected (this will get very annoying for users to wait every time for the server to refresh the data)

That being said, the issue with the code you posted is that you're initializing a new instance of your classes in the TabBarControllerDelegate method so the method will be called on this new instance instead of on the one that's displaying/exists in your TabBarController's view controllers. Specifically these two lines are initializing the new instances:

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

Instead you should be finding the instance that already exists, and calling the method on them.

I would recommend creating a ParentViewController with a public method along the lines of - (void)doStuffWhenTabBarControllerSelects; (just example naming to be clear what's it doing to you) then have each of the view controllers you'd like to have do something when they're selected be child classes of this parent (and have their own implementation of - (void)doStuffWhenTabBarControllerSelects;). This way in the TabBarController's delegate method, you can just find the appropriate instance of ParentViewController (associated with the view controller being selected) and call the - (void)doStuffWhenTabBarControllerSelects; method on it.

Here's an example of what I mean:

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

Then when you select between the two tabs you'll this is the output:

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

I'd recommend doing some additional research/reading of the documentation:

There's a good amount of beginner information here: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/DefiningClasses/DefiningClasses.html#//apple_ref/doc/uid/TP40011210-CH3-SW1

UITabBarController: https://developer.apple.com/documentation/uikit/uitabbarcontroller?language=objc

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

One other helpful hint is that within Xcode you can hold down on the option key and click on something to show a quicklook into the explanation/documentation

You can also right click on something and "Jump To Definition". The majority of Apple's implementations will will have additional information in the header.

Here's the example of what's in the header of UITabBarController:

/*!
 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>

As well as under the Help Menu there's "Developer Documentation" (CMD + SHIFT + 0) which has a multitude of useful information.



来源:https://stackoverflow.com/questions/52306981/objective-c-tabbaritem-tapped-method-called-but-webview-not-refreshed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!