使用init方法创建类类别

时间:2012-12-20 09:38:15

标签: objective-c uistoryboard uiactivityindicatorview

我正在尝试为UIActivityIndi​​catorView创建一个类类别 - 我想在屏幕中心设置它。

所以我宣布:

@implementation UIActivityIndicatorView(Normalize)

-(UIActivityIndicatorView *) setAtScreenCenter{
    CGRect r = [UIScreen mainScreen].applicationFrame;
    CGRect wheelR = CGRectMake(r.size.width / 2 - 12, r.size.height / 2 - 12, 24, 24);
    self = [[UIActivityIndicatorView alloc] initWithFrame:wheelR];
    self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
    self.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
                                      UIViewAutoresizingFlexibleRightMargin |
                                      UIViewAutoresizingFlexibleTopMargin |
                                      UIViewAutoresizingFlexibleBottomMargin);
    return self;
}
@end

使用方法: [activityWheel setAtScreenCenter];

但是,我收到了编译错误:

Cannot assign to 'self' outside of a method in the init family

3 个答案:

答案 0 :(得分:3)

您的setAtScreenCenter是一条实例消息。您必须将其发送到现有UIActivityIndicatorView。为什么要尝试在此方法中创建 new UIActivityIndicatorView

请改为尝试:

self.frame = wheelR;

您可能对坐标如何工作感到困惑。视图的框架与其superview的坐标系相关。它与屏幕坐标系无关。即使您的超级视图是全屏的,它的坐标系也会与屏幕的坐标系不同,除了一个方向。您可以像这样转换坐标:

CGRect frame = [UIScreen mainScreen].applicationFrame;
CGPoint p = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame));
p = [self.window convertPoint:p fromWindow:nil]; // convert screen -> window
p = [self.superview convertPoint:p fromView:nil]; // convert window -> my superview
self.center = p;

答案 1 :(得分:2)

警告不仅仅是迂腐,编译器实际上是在拯救你自己。您应该声明要返回的新UIActivityIndi​​cator var,而不是尝试分配给self。该方法的更好版本如下所示:

+(UIActivityIndicatorView *)setAtScreenCenter{
    CGRect r = [UIScreen mainScreen].applicationFrame;
    CGRect wheelR = CGRectMake(r.size.width / 2 - 12, r.size.height / 2 - 12, 24, 24);
    UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithFrame:wheelR];
    indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
    indicator.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
                                  UIViewAutoresizingFlexibleRightMargin |
                                  UIViewAutoresizingFlexibleTopMargin |
                                  UIViewAutoresizingFlexibleBottomMargin);
    return indicator;
}

作为一个类方法,我们不再需要处理赋值给self,并且始终可以保证满足方法的返回类型(如果这是一个真正的初始化器,它将返回id更容易的子类化。)

答案 2 :(得分:1)

这不是一个真正的init方法。因此,你不应该在这里指定自己。只需跳过该行并使该方法成为void方法(无返回值)。

@implementation UIActivityIndicatorView(Normalize)

-(void) setAtScreenCenter{
    CGRect r = [UIScreen mainScreen].applicationFrame;
    CGRect wheelR = CGRectMake(r.size.width / 2 - 12, r.size.height / 2 - 12, 24, 24);
    self.frame = wheelR;
    self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
    self.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
                                      UIViewAutoresizingFlexibleRightMargin |
                                      UIViewAutoresizingFlexibleTopMargin |
                                      UIViewAutoresizingFlexibleBottomMargin);

}
@end

现在您可以在现有的UIActivityIndi​​catorView上调用它来设置它想要的位置:

[activityWheel setAtScreenCenter];