现在,我对我为创建自定义视图而创建的这个hacky变通方法感到不满。它在initWithFrame的另一个视图控制器中以编程方式初始化,因此我在代码中重写了它。这似乎不是初始化我的视图的正确方法,但我不确定还能做什么。
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self = [[[NSBundle mainBundle] loadNibNamed:@"OTGMarkerDetailView" owner:self options:nil] lastObject];
[self setFrame:frame];
}
return self;
}
如果没有setFrame方法,自定义视图似乎总是在窗口顶部而不是在我用CGRectMake指定的坐标处创建。
我在视图控制器中的方法中初始化视图。
- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
if (!self.detailView) {
self.detailView = [[OTGMarkerDetailView alloc] initWithFrame:CGRectMake(0, 568, 320, 55)];
}
[self.view addSubview:self.detailView];
self.detailView.backgroundColor = [UIColor whiteColor];
NSRange range = [self.startAddress rangeOfString:@","];
NSString *mainAddress = [self.startAddress substringToIndex:range.location];
NSString *subAddress = [self.startAddress substringFromIndex:range.location + 1];
[self.detailView setLabelsWithMainAddress:mainAddress subAddress:subAddress];
[UIView animateWithDuration:0.5 animations:^{
self.detailView.frame = CGRectMake(0, 513, 320, 55);
}];
return YES;
}
答案 0 :(得分:0)
mapView
方法为什么不执行init
方法所做的操作,即直接将视图拉出其笔尖?换句话说,为什么你要隐藏mapView
获取此视图实例的方法是加载一个笔尖?没有理由隐瞒这一事实。
或者,如果你想隐藏这个事实,为什么不把一个便利构造函数作为视图的类方法而不是误用initWithFrame
?例如[OTGMarkerDetailView makeADetailView]
...
答案 1 :(得分:0)
一般来说,处理这类事情的最佳方法是使用类工厂方法:
+(instancetype)markerDetailView {
[[[NSBundle mainBundle] loadNibNamed:@"OTGMarkerDetailView" owner:nil options:nil] lastObject];
}
然后使用以下命令创建视图:
self.detailView = [OTGMarkerDetailView markerDetailView];
请注意,我还希望采用更加类型安全的方法从nib文件加载视图:
+(instancetype)markerDetailView {
for(OTGMarkerDetailView* view in [[NSBundle mainBundle] loadNibNamed:@"OTGMarkerDetailView" owner:nil options:nil]) {
if([view isKindOfClass:[OTGMarkerDetailView class]]) {
return view;
}
}
NSAssert(false, @"Failed to load OTGMarkerDetailView");
return nil;
}
如果您需要在InterfaceBuilder中使用自定义视图的实例,则必须覆盖initWithCoder:
和initWithFrame:
。由于您要替换自己,因此我们确实无需拨打super
:
-(id)initWithCoder:(NSCoder*)aDecoder {
self = [[self class] markerDetailView];
// I think this will work to inherit settable properties in IB
if((self = [super initWithCoder:aDecoder])) {
// support any additional settable properties in IB
}
return self;
}