5

I'm trying to pass a CGRect:

SEL frameSel = NSSelectorFromString(@"setFrame:");
CGRect rect = CGRectMake(10, 10, 200, 100);
[object performSelector:frameSel withObject:rect ];

But this does not compile

I also tried:

SEL frameSel = NSSelectorFromString(@"setFrame:");
CGRect rect = CGRectMake(10, 10, 200, 100);
NSValue * value = [NSValue valueWithCGRect:rect];
[object performSelector:frameSel withObject:value ];

Actually, this does compile but when I debug, the frame is not setted correctly:

po object
<UILabel: 0x39220f0; frame = (0 0; 200 100); text = 'reflectionLabel'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x3922240>>

But it should be frame = (10 10; 200 100)

How can I solve this problem?

Thank you in advance!

Keavon
  • 6,837
  • 9
  • 51
  • 79
Fabrizio Farinelli
  • 241
  • 1
  • 4
  • 8

2 Answers2

5
CGRect rect = CGRectMake(10, 10, 200, 100);
[object performSelector:frameSel withObject:rect ];

But this does not compile

Correct, because rect is a structure, not a pointer to an object.

CGRect rect = CGRectMake(10, 10, 200, 100);
NSValue * value = [NSValue valueWithCGRect:rect];
[object performSelector:frameSel withObject:value ];

Actually, this does compile but when I debug, the frame is not setted correctly:

po object
<UILabel: 0x39220f0; frame = (0 0; 200 100); text = 'reflectionLabel'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x3922240>>

Well, it's not garbage, so it would seem that it worked, even though the origin somehow remained zero. You may want to ask a separate question about that.

Anyway, why are you using performSelector:withObject:? You're not addressing it to a specific thread and you're not putting it on a delay; why not simply say object.frame = rect?

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
  • Object is of type NSObject * I cannot simply say object.frame I really need to use NSObject* >>> Well, it's not garbage, so it would seem that it worked, even though the origin somehow remained zero. You may want to ask a separate question about that. I really need an answer on that question. Thanks!! – Fabrizio Farinelli Feb 20 '10 at 16:15
  • If you know it has a `frame` property, cast it to `UIView *` and then use `object.frame = rect`. If you don't know it has a `frame` property, use KVC (http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/KeyValueCoding/) to set the property, and catch the exception that will happen if it doesn't have one. – Peter Hosey Feb 20 '10 at 17:00
5

You must use an NSInvocation to handle any non-id arguments or return values:

CGRect rect = CGRectMake(104, 300, 105, 106);
UIView *view = [[UIView alloc] init];

NSMethodSignature *methodSig = [view methodSignatureForSelector:@selector(setFrame:)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
invocation.target = view;
invocation.selector = @selector(setFrame:);
[invocation setArgument:&rect atIndex:2];
[invocation invoke];
syang
  • 51
  • 1
  • 1