如何从现有对象的不同类调用方法(Obj C)
Posted
技术标签:
【中文标题】如何从现有对象的不同类调用方法(Obj C)【英文标题】:How do I call a method from a different class on an existing object (Obj C) 【发布时间】:2013-03-15 11:51:14 【问题描述】:我是 Objective C 和 Xcode 的新手,可能只是做一些愚蠢的错误,但我尝试了很多不同的建议,但无法让它们发挥作用。
简而言之,当在不同的 UIViewController 中按下按钮时,我想调用现有 UIViewController 上的方法。
(有点背景:两个屏幕是一个主屏幕和一个菜单屏幕。用户向上滑动查看菜单,然后当完成按钮按下我希望菜单屏幕将字符串变量(在本例中为 URL)发送到主屏幕中的方法,然后主屏幕在 UIWebView 中显示 URL。
我尝试将方法/URL 变量放入 AppDelegate/MainViewController 并合成它们。我还尝试使 MenuViewController 成为 MainViewCONtroller 的子类并使用 [super readFile:url] 调用该方法,该方法确实编译但我认为它没有调用现有的 MainViewController 对象,因为 webview 没有出现。
我将在下面粘贴我的代码的相关部分:(感谢您的帮助!)
MainViewController.h
#import <UIKit/UIKit.h>
@interface MainViewController : UIViewController
IBOutlet UIWebView *vCodeView;
- (void)readFile:(NSString *)newURL;
@end
MainViewController.m
#import "MainViewController.h"
#import "MenuViewController.h"
@interface MainViewController ()
@end
@implementation MainViewController
- (void)readFile:(NSString *)newURL
vCodeView.hidden = NO;
// seperate url by full stops
NSArray *splitURL = [newURL componentsSeparatedByString:@"."];
// find extension of file
NSString *extension = [splitURL objectAtIndex:([splitURL count]-1)];
// DO SOME OTHER STUFF WITH URL THEN DISPLAY CONTENT IN UIWEBVIEW
- (void)swipeUpRecognised
MenuViewController *menuView = [[MenuViewController alloc] initWithNibName:@"MenuViewController" bundle:nil];
menuView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:menuView animated:YES completion:nil];
MenuViewController.h
#import <UIKit/UIKit.h>
#import "MainViewController.h"
@interface MenuViewController : UIViewController
IBOutlet UIBarButtonItem *bDone;
IBOutlet UITextField *fUser;
IBOutlet UITextField *fPass;
IBOutlet UITextField *fAddress;
IBOutlet UITextField *fAutoConnectAddress;
- (IBAction)bDonePressed;
@end
MenuViewController.m
#import "MenuViewController.h"
#import "MainViewController.h"
@interface MenuViewController ()
@end
@implementation MenuViewController
- (IBAction)bDonePressed
NSString *user = @"admin";
NSString *pass = @"password";
NSString *path = @"54.246.90.95/repos/project1/trunk/dir1/test.c";
// url of file
NSArray *pathArray = [[NSArray alloc] initWithObjects:@"http://", user, @":", pass, @"@", path, nil];
NSString *url = [pathArray componentsJoinedByString:@""];
//call the method here passing in url
[self dismissViewControllerAnimated:YES completion:nil];
【问题讨论】:
在 appdelegate.m 文件中声明你的方法,而不是从你的类中调用 @keyur 这是一个非常糟糕的主意。这会让他的视图控制器知道他的应用程序委托中的方法。 你的实现中的一个小错误:你通常会有[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
【参考方案1】:
在这种特殊情况下,您可以在dismissViewControllerAnimated
调用之前输入以下内容,它应该可以工作:
if(self.presentingViewController && [self.presentingViewController respondsToSelector:@selector(readFile:)])
[(id)self.presentingViewController readFile:url];
一般来说,你真正想要的是Delegation。
所以,为了更简洁的实现,试试这个:
MenuViewController.h
@protocol MenuViewControllerDelegate <NSObject>
- (void)menuViewControllerFinishedWithURL:(NSURL *)url;
@end
@interface MenuViewController : UIViewController
@property id<MenuViewControllerDelegate> delegate;
// ...
MenuViewController.m
- (IBAction)bDonePressed
// ...
if(self.delegate)
[self.delegate menuViewControllerFinishedWithURL:url];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
MainViewController.m
@interface MainViewController () <MenuViewControllerDelegate>
@end
// ...
- (void)swipeUpRecognised
MenuViewController *menuView = [[MenuViewController alloc] initWithNibName:@"MenuViewController" bundle:nil];
menuView.delegate = self;
menuView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:menuView animated:YES completion:nil];
【讨论】:
非常感谢!这几天我一直在尝试不同的解决方案! :)【参考方案2】:为了调用 MainViewController 方法,应该很简单:
-
将 MainViewController.h 包含到 MenuViewController.h 中。
在你想要的地方调用这个 sn-p:
NSString * vcid = @""; //put id you have assigned to your MainViewController. This should be in your storyboard. If it is empty, fill it with proper name, then use it here.
UIStoryboard *storybord = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
MainViewController *mainvc =[storybord instantiateviewcontrollerwithidentifier:vcid];
[mainvc method];
注意method
必须在 MainViewController.h 文件中声明才能被调用。
也就是说,我想知道您是否真的需要为菜单设置单独的视图控制器。如果您想为用户提供一组按钮以供选择,请考虑包含所有按钮的 UIView。这个 UIView 应该会在你的swipeUpRecognised
中弹出。
【讨论】:
对不起,我可能应该提一下,我使用的是 .xib 而不是故事板。不管怎么说,还是要谢谢你! :) 即使在那里你也应该能够指定这个属性。只需选择视图控制器,然后查看属性检查器显示的内容。【参考方案3】:此代码将适用于您... 像这样修改你的代码....
MainViewController.h
#import <UIKit/UIKit.h>
@interface MainViewController : UIViewController
IBOutlet UIWebView *vCodeView;
- (void)readFile:(NSString *)newURL;
@end
MainViewController.m
#import "MainViewController.h"
#import "MenuViewController.h"
@interface MainViewController ()
@end
@implementation MainViewController
- (void)readFile:(NSString *)newURL
vCodeView.hidden = NO;
// seperate url by full stops
NSArray *splitURL = [newURL componentsSeparatedByString:@"."];
// find extension of file
NSString *extension = [splitURL objectAtIndex:([splitURL count]-1)];
// DO SOME OTHER STUFF WITH URL THEN DISPLAY CONTENT IN UIWEBVIEW
- (void)swipeUpRecognised
MenuViewController *menuView = [[MenuViewController alloc] initWithNibName:@"MenuViewController" bundle:nil];
menuView.delegate = self;
menuView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:menuView animated:YES completion:nil];
MenuViewController.h
#import <UIKit/UIKit.h>
#import "MainViewController.h"
@interface MenuViewController : UIViewController
IBOutlet UIBarButtonItem *bDone;
IBOutlet UITextField *fUser;
IBOutlet UITextField *fPass;
IBOutlet UITextField *fAddress;
IBOutlet UITextField *fAutoConnectAddress;
@property(nonatomic, retain) MainViewController *delegate;
- (IBAction)bDonePressed;
@end
MenuViewController.m
#import "MenuViewController.h"
#import "MainViewController.h"
@interface MenuViewController ()
@end
@implementation MenuViewController
@synthesize delegate = _delegate;
- (IBAction)bDonePressed
NSString *user = @"admin";
NSString *pass = @"password";
NSString *path = @"54.246.90.95/repos/project1/trunk/dir1/test.c";
// url of file
NSArray *pathArray = [[NSArray alloc] initWithObjects:@"http://", user, @":", pass, @"@", path, nil];
NSString *url = [pathArray componentsJoinedByString:@""];
//call the method here passing in url
[self.delegate readFile:url];
[self dismissViewControllerAnimated:YES completion:nil];
【讨论】:
以上是关于如何从现有对象的不同类调用方法(Obj C)的主要内容,如果未能解决你的问题,请参考以下文章