当UIViewController的子类未知时,如何使用UIViewController创建类

时间:2013-03-11 18:23:35

标签: ios objective-c uiview uiviewcontroller

标题是我认为我需要的,但我会退后一步。我想创建一个处理iOS应用程序中某些内容的类。 iOS应用中的多个UIViewcontrollers可能会调用此类。该类可能需要在某个阶段显示UIView以供用户输入。所以我的问题是,当我不知道UIView subclass正在调用它时,如何显示UIViewController?我可以从这个类中添加UIView

我想有两个可能的答案是,类找到当前的UIViewController或者UIViewController的调用子类将自己传递给类,所以类知道。

这应该如何完成。

谢谢你的帮助。

3 个答案:

答案 0 :(得分:0)

您可以将该类转换为字符串并进行比较。

例如,假设您的自定义UIViewController子类为CustomViewConUIViewController对象引用为myUnknownClassObject,则为:

NSString *classString = NSStringFromClass([myUnknownClassObject class]);

然后你可以:

if([classString isEqualToString:@"CustomViewCon"]){
    //do something like maybe present a particular view
    myUnknownClassObject.view = myCustomView; //or anything..
}

同样,你可以检查任何课程。

编辑:根据评论中的建议,您还可以执行以下操作(更好的方法):

if([[myUnknownClassObject class] isKindOfClass:[CustomViewCon class]]){
    //same as before
}

答案 1 :(得分:0)

我将扩展@ ericleaf关于使用协议和子类的评论。听起来你问的是:

  

如何创建一个可呈现视图的可重用通用类   在UIViewController子类中?

执行此操作的一种好方法是在泛型类中定义协议,并让视图控制器子类支持此协议。该协议为您的自定义类定义了一个接口,以便与它的delegate进行通信,在本例中为UIViewController子类。除了协议之外,对象不需要知道关于彼此实现的任何其他内容。

您的自定义对象需要能够在其委托中呈现视图的任何信息都将通过协议方法传递。协议的细节取决于您的需求。您可以让自定义对象“询问”代理人的信息(例如,我应该将子视图放在哪个视图中?)或者您可以让协议向代理人提供信息并让代理人处理它(例如,这是一个子视图你可以放在你想要的任何地方。)

关于SO和其他地方可用的协议,有很多很棒的文档。这已经够了,所以我保持这个例子相当简单。

具有协议定义的自定义类.h文件

// my custom class that adds adds a view to a view controller that supports it's protocol

// forward class definition for the protocol
@class MyAwesomeObject;

@protocol MyAweseomeObjectDelegate <NSObject>
- (UIView *)viewForMyAwesomeObject:(MyAwesomeObject *)awesomeObject;
@end

// this could be defined such that the delegate *must* be a UIViewController. I've left it generic.
@interface MyAwesomeClassObject : NSObject
@property (nonatomic, weak) id <MyAwesomeObjectDelegate> delegate;
@end

自定义类.m文件

// MyAwesomeObject.m

#import "MyAwesomeObject.h"

@implementation MyAwesomeObject

// this is a dumb example, but shows how to get the view from the delegate
// and add a subview to it
- (void)presentViewInDelegate
{
    UIView *containingView = [self.delegate viewForMyAwesomeObject:self];
    if (containingView) {
        UIView *subview = [[UIView alloc] initWithFrame:containingView.bounds];
        subview.backgroundColor = [UIColor redColor];
        subview.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
        [containingView addSubview:subview];
    }
}

MyViewController .h使用自定义对象

// MyViewController.h

@import "MyAwesomeObject.h"

@interface MyViewController : UIViewController <MyAwesomeObjectDelegate>
@property (nonatomic, strong) MyAwesomeObject *awesomeObject;
@end

MyViewController .m使用自定义对象

// MyViewController.m

@import "MyViewController.h"

@implementation MyViewController

- (void)init
{
    self = [super init];
    if (self) {
        _awesomeObject = [[MyAwesomeObject alloc] init];
        _awesomeObject.delegate = self;
    }
    return self;
}

// MyAwesomeObjectDelegate
- (UIView *)viewForMyAwesomeObject:(MyAwesomeObject *)awesomeObject
{
    return self.view;
}

答案 2 :(得分:0)

为什么不用这个块呢? BaseViewController.h:

@property (copy) void (^addViewBlock)();
- (IBAction)showViewWhenNeeded;

BaseViewController.m:

- (IBAction)showViewWhenNeeded
{
    if (self.addViewBlock)
        self.addViewBlock();
}

在您的子课程中,设置该块的操作,并在您认为应该放置视图时调用该方法。

ChildViewController.m

// within some method, propably init or smth
[self setAddViewBlock:^{
    [self.vied addSubView:...];
}];

// when need to actually add the view
[self showViewWhenNeeded];