In my application i have an UIViewController
that i uses a lot of UIAlertView
to ask things to the user.
Because i need the response of each UIAlertView
i have made my controller a delegate of UIAlertViewDelegate
, this works fine but after 7 UIAlertView
's i`m trying to find a better way to use delegates.
In java i know that i can create inline classes for a single purpose, like in this question: Java - inline class definition
What i want to know is: Is there a way to create a class to be delegate dynamically? to achieve something like this
id<UIAlertViewDelegate> myCustomClass = @class {
my class code goes here
}
UIAlertView* alertView;
alertView = [[UIAlertView alloc] initWithTitle:@"Title"
message:@"Message"
delegate:myCustomClass
cancelButtonTitle:@"No"
otherButtonTitles:@"OK", @"Sure", @"Maybe", nil] ];
[alertView show];
No - there are no 'inline classes' in Objective-C. With that said, you can create custom objects at run-time with objective-c, which is a little bit more involved, but I'd be willing to share some code to do what you are saying.
Here is an example of that:
NSObject+Subclass.h
#import <objc/runtime.h>
typedef struct selBlockPair { SEL aSEL; id (^__unsafe_unretained aBlock)(id, ...); } selBlockPair;
#define NIL_PAIR ((struct selBlockPair) { 0, 0 })
#define PAIR_LIST (struct selBlockPair [])
#define BLOCK_CAST (id (^)(id, ...))
@interface NSObject (subclass)
+(Class) newSubclassNamed:(NSString *) name
protocols:(Protocol **) protos
impls:(selBlockPair *) impls;
@end
NSObject+Subclass.m
@implementation NSObject (subclass)
+(Class) newSubclassNamed:(NSString *)name
protocols:(Protocol **)protos
impls:(selBlockPair *)impls
{
if (name == nil)
{
// basically create a random name
name = [NSString stringWithFormat:@"%s_%i_%i", class_getName(self), arc4random(), arc4random()];
}
// allocated a new class as a subclass of self (so I could use this on a NSArray if I wanted)
Class newClass = objc_allocateClassPair(self, [name UTF8String], 0);
// add all of the protocols untill we hit null
while (protos && *protos != NULL)
{
class_addProtocol(newClass, *protos);
protos++;
}
// add all the impls till we hit null
while (impls && impls->aSEL)
{
class_addMethod(newClass, impls->aSEL, imp_implementationWithBlock(impls->aBlock), "@@:*");
impls++;
}
// register our class pair
objc_registerClassPair(newClass);
return newClass;
}
@end
Example Usage:
int main()
{
@autoreleasepool {
__strong Class newClass = [NSString newSubclassNamed:@"MyCustomString" protocols:NULL impls: PAIR_LIST {
@selector(description),
BLOCK_CAST ^id (id self) {
return @"testing";
},
NIL_PAIR
}];
NSString *someString = [newClass new];
NSLog(@"%@", someString);
}
}
Output:
2012-10-01 10:07:33.609 TestProj[54428:303] testing
This type of Java anonymous inner class is not something that is supported in Objective-C. If you want to respond to the delegates individually, I good way is to experiment with blocks.
Unfortunately, Apple has not added blocks into UIAlertViews, but you can implement them yourself. A bunch of people have done this online. Take a look here: http://blog.mugunthkumar.com/coding/ios-code-block-based-uialertview-and-uiactionsheet/ or https://github.com/MugunthKumar/UIKitCategoryAdditions .
The basic idea is that you can create a subclass (or a category if using associated objects), that will be its own delegate and tell its own delegate to call a block you pass in
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With