I am trying to use invocation to callback a UIView
in Objective C and toggle its hidden
property. The message must be sent to a custom view in a dedicated class SquareView
.
For demonstration purposes my invokerMethod
will be called from a UIButton.
The appropriate place for this and the SquareView
property would seem to be the UIViewController.
But I can’t tell whether invocation is meant to return a value and my sample code gives the following error
+[NSInvocation _invocationWithMethodSignature:frame:]: method signature argument cannot be nil'
Can someone please point out what I have got wrong. The examples of NSInvocation
I’ve looked at here here and here have so far not shed any light on this. And this link is dead.
EDIT
This may be a duplicate question but the answer did not fix my problem. But I found another question on invocation with answers that helped produce a simpler version of what I am trying to do, with a slightly different problem related to the one here in this post.
Here is my code so far
ViewController.h
#import <UIKit/UIKit.h>
#import "SquareView.h"
@interface ViewController : UIViewController
@property (nonatomic, weak) UIView* square;
@end
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
SquareView *square = [[SquareView alloc] initWithFrame:CGRectMake(60, 60, 100, 100)];
[self.view addSubview:square]; // draw once only
[self.view addSubview:[self button:CGRectMake(120, 230, 100, 50)]];
SEL selector = @selector(invokerMethod:);
BOOL toggle;
UIView *target = _square;
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[target methodSignatureForSelector:selector]];
invocation.selector = selector;
invocation.target = target;
[invocation setArgument:&toggle atIndex:2];
[invocation invoke];
__weak id returnValue = nil;
[invocation getReturnValue:&returnValue];
}
Here is the invoker method …
- (id)invokerMethod:(NSInteger)tag
{
NSLog(@"toggle view each time”);
if (_square)
{
if (_square.hidden)
{
[_square setHidden:NO];
}
else
{
[_square setHidden:YES];
}
}
return nil;
}
… and here is the button method …
- (UIButton *)button:(CGRect)box
{
UIButton *tap = [[UIButton alloc] initWithFrame:box];
tap.backgroundColor = [UIColor lightGrayColor];
[tap setTitle:@“toggle" forState:UIControlStateNormal];
[tap addTarget:self action:@selector(invokerMethod) forControlEvents:UIControlEventTouchUpInside];
return tap;
}
… and here is the view that gets toggled.
SquareView.h
#import <UIKit/UIKit.h>
@interface SquareView : UIView
@end
SquareView.m
#import "SquareView.h"
@implementation SquareView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
UIView *square = [[UIView alloc] initWithFrame:frame];
square.backgroundColor = [UIColor redColor];
[self addSubview:square];
}
return self;
}
@end