如何从类本身内初始化自定义视图控制器?

时间:2015-03-06 07:33:25

标签: ios objective-c cocoa-touch uiviewcontroller

我尝试使用第三方库MBPullDownController制作类似Google地图应用中的向上滑动面板的内容。

以下是图书馆的示例代码:

UITableViewController *front = [[UITableViewController new];
UIViewController *back = [[UIViewController new];
MBPullDownController *pullDownController = [[MBPullDownController alloc] initWithFrontController:front backController:back];
[self.navigationController pushViewController:pullDownController animated:NO];

从其他视图控制器导航到它时工作正常。然而,我的地图控制器有四个或五个其他视图控制器直接导致它,所以我试图从地图控制器本身进行初始化。

我尝试将我的视图控制器作为MBPullDownController的子类,并尝试在initUsingCoder:方法中对其进行初始化,如下所示:

MapViewController.h

#import <UIKit/UIKit.h>
#import <GoogleMaps/GoogleMaps.h>
#import "MBPullDownController.h"
....

@interface MapViewController : MBPullDownController<GMSMapViewDelegate>
....
@end

MapViewController.m

#import "MapViewController.h"
#import <GoogleMaps/GoogleMaps.h>
#import "LocationUtility.h"
#import "MBPullDownController.h"
...

@interface MapViewController () <CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@end

@implementation MapViewController {
    GMSMapView *mapView;
    NSMutableDictionary *markers;
}

@implementation MapViewController {
GMSMapView *mapView;
NSMutableDictionary *markers;
UITableViewController *front;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        front = [UITableViewController new];
        self = (MapViewController *)[[MBPullDownController alloc]initWithFrontController:front backController:self ];
    }
    return self;
}
....

我收到警告'This coder requires that replaced objects be returned from initWithCoder:',显然是因为self = [super initWithCoder:aDecoder]self = (MapViewController *)[[MBPullDownController alloc]initWithFrontController:front backController:self ];取代

如何正确地将视图控制器初始化为MBPullDownController?

2 个答案:

答案 0 :(得分:0)

我实际上在写这个问题的过程中找到了解决方案,但我认为我会继续帮助其他有相同问题的人,因为答案不容易找到。

解决方案是使用-(id)awakeAfterUsingCoder:(NSCoder *)aDecoder方法,&#34;允许您替换另一个对象来代替已解码的对象&#34; (source)

- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder
{
    if (self) {
        front = [UITableViewController new];
        self = (MapViewController *)[[MBPullDownController alloc]initWithFrontController:front backController:self ];
    }
    return self;
}

答案 1 :(得分:0)

问题是您正在尝试使用初始化程序initWithFrontController来初始化MBPullDownController的实例而不是initWithCoder,这是iOS在从nib实例化对象时强制您调用的。

该库应该有另一个名为initWithCoder的方法:andFrontController:andBackController,它负责调用super plus并正确设置子控制器。

然而,由于没有提供,似乎创建者做了两个属性frontController和backController public。这通常(如果他做得好)意味着你可以在调用initializr后自由设置这些属性。所以我会尝试:

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        self.frontController = [UITableViewController new];
        self.backController = self;
    }
    return self;  
}

如果这不起作用,你应该在github中创建一个问题,并告诉创建者添加initWithCoder初始化程序,并使用awakeAfterUsingCoder保存你的解决方案