Reputation: 14317
I am trying to create a class category for UIActivityIndicatorView - I would like to set it in the screen center.
So I declared:
@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
Usage: [activityWheel setAtScreenCenter];
However, I get a compilation error:
Cannot assign to 'self' outside of a method in the init family
Upvotes: 1
Views: 1555
Reputation: 385890
Your setAtScreenCenter
is an instance message. You have to send it to an existing UIActivityIndicatorView
. Why would you try to create a new UIActivityIndicatorView
in this method?
Try this instead:
self.frame = wheelR;
You may also be rather confused about how coordinates work. The view's frame is relative to its superview's coordinate system. It's not relative to the screen coordinate system. Even if your superview is full screen, its coordinate system will be different from the screen's coordinate system in all but one orientation. You can convert the coordinates like this:
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;
Upvotes: 3
Reputation: 989
This is not really an init method. Therefore you should not assign to self here. Just skip that line and make the method a void method (no return value).
@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
Now you can call it on an existing UIActivityIndicatorView to set its position like you wanted:
[activityWheel setAtScreenCenter];
Upvotes: 1
Reputation: 43330
The warning is more than just pedantry, the compiler is actually saving you from yourself. You should be declaring a new UIActivityIndicator var to return, instead of trying to assign to self. A better version of the method would look like this:
+(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;
}
As a class method, we no longer have to deal with assigning to self, and you can always be guaranteed to satisfy the return type of the method (if this were a true initializer, it would return id
for easier subclassing).
Upvotes: 2