这是主要想法
+---MyViewController.m----+ +---BtnOnClickResp.m-----+
| | EventTouchUpInside: | |
| Button ---------------------------------------> OnBtnClick() |
| | textView.text=@"blabla"| | |
| *textView <------------------------------------------ + |
| | | |
+-------------------------+ +------------------------+
我想测试是否可以在另一个控制器中按下按钮OnClick
,如下所示:
MyViewController.h
#import <UIKit/UIKit.h>
@interface MyViewController : UIViewController
@property (nonatomic, strong) UITextView *textView;
+(id) sharedInstance;
@end
MyViewController.m
#import "MyViewController.h"
#import "BtnOnClickResp.h"
@interface MyViewController ()
@end
@implementation MyViewController
@synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = @"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:@"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:[[BtnOnClickResp alloc] init] action:@selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
@end
BtnOnClickResp.h
#import <UIKit/UIKit.h>
@interface BtnOnClickResp : UIViewController
@end
BtnOnClickResp.m
#import "BtnOnClickResp.h"
#import "MyViewController.h"
@interface BtnOnClickResp ()
@end
@implementation BtnOnClickResp
- (void) onBtnClick: (UIButton *) btn{
NSLog(@"btn was click but I am in another controller");
MyViewController *control = [MyViewController sharedInstance];
control.textView.text = @" I am setting this content in another view cheers!!!";
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
主要的想法是在MyViewController
中绘制/添加一个按钮视图并在另一个控制器中点击代码做出响应,我想到了动作分配代码:
[btn addTarget:self action:@selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
如果我们将self
更改为我们想要使用的实际控制器,则会将click事件分派给该控制器
但似乎没有用。
如果你不打算回答这个初学者的问题,那么ios开发的初学者会很高兴。
在接受@Mike建议后的建议后,
我将MyViewController.m
更改为:
#import "MyViewController.h"
#import "BtnOnClickResp.h"
@interface MyViewController (){
//here is the change , I made a private ref of the controller
BtnOnClickResp *respContl;
}
@end
@implementation MyViewController
@synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = @"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:@"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:respContl action:@selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
respContl = [[BtnOnClickResp alloc] init];
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
@end
现在我可以看到btn was click but I am in another controller
的NSLog,但视图内容仍未保持@" I am setting this content in another view cheers!!!"
,因为它预期位于BtnOnClickResp.m
这是AppDelagate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController *control = [[MyViewController alloc] init];
[self.window setRootViewController:control];
[self.window setBackgroundColor:[UIColor greenColor]];
[self.window makeKeyAndVisible];
// Override point for customization after application launch.
return YES;
}
答案 0 :(得分:0)
您正在添加目标
[btn addTarget:[[BtnOnClickResp alloc] init] action:@selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
到
[BtnOnClickResp alloc] init]
错了
因为它会创建新实例并为其添加侦听器。 但是,您尝试访问其他实例中的操作
你有4个解决方案
BtnOnClickResp
的共享实例并为其指定目标self
的{{1}}传递给BtnOnClickResp
并分配创建代表
发布通知
答案 1 :(得分:0)
声明BtnOnClickResp的属性并将其设置为按钮目标。
#import "MyViewController.h"
#import "BtnOnClickResp.h"
@interface MyViewController ()
@property(nonatomic, strong) BtnOnClickResp onClickRespObj;
@end
@implementation MyViewController
@synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (id)init{
if(self = [super init]){
self.onClickRespObj = [[BtnOnClickResp alloc] init];
}
return self;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = @"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:@"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:self.onClickRespObj action:@selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
@end