Objective-C: 点击 Tabbaritem-> 调用方法-> 但 WebView 未刷新
Objective-C: Tabbaritem tapped->Method Called-> But WebView not refreshed
正在努力实现
当我点击 tabbaritem 说 #2 时,它会调用该方法并重新加载网络视图。
问题
当我点击 tabbaritem 时,该方法被调用,但网页视图没有重新加载。
问题
如果我在 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 文档:
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),其中包含大量有用的信息。
正在努力实现
当我点击 tabbaritem 说 #2 时,它会调用该方法并重新加载网络视图。
问题
当我点击 tabbaritem 时,该方法被调用,但网页视图没有重新加载。
问题
如果我在 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 文档:
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),其中包含大量有用的信息。