Question

In my viewDidLoad, I call a function:

[common startActivityIndicatorOnView:self.view];

This method adds a view with Activity indicator, in the center of self.view. My current view is pushed on a Navigation Stack. This is how the view looks after this method returns (the activity indicator view is not in center): enter image description here

However, if I call the same method this way:

[common performSelectorOnMainThread:@selector(startActivityIndicatorOnView:) withObject:self.view waitUntilDone:NO];

The view looks like the following image (the activity indicator view is in center):

enter image description here

I do not get, How does it make a difference if the calling line is written in viewDidLoad. If any one can help me get this, thanks in advance.

Just for reference, the method looks like this:

-(void) startActivityIndicatorOnView:(UIView *)view {
    if ([NSRunLoop currentRunLoop] != [NSRunLoop mainRunLoop]) {
        [self performSelectorOnMainThread:@selector(startActivityIndicatorOnView:) withObject:view waitUntilDone:NO];
        return;
    }
    view.userInteractionEnabled = NO;
    activityBgView = [[UIView alloc] initWithFrame:CGRectMake((view.frame.size.width/2) - 50, (view.frame.size.width/2) - 50, 100, 100)];
    activityBgView.center = view.center;
    activityBgView.backgroundColor = [UIColor grayColor];
    activityBgView.alpha = 0.8;
    spinner = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake((activityBgView.frame.size.width/2)-10, (activityBgView.frame.size.width/2)-10, 20, 20)];
    spinner.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
    spinner.center = view.center;

    [view addSubview:activityBgView];
    [view addSubview:spinner];
    [spinner startAnimating];
}
Was it helpful?

Solution

ViewDidLoad is called when you load viewControllers (via nib/xib or created programmatically in the loadView method), meaning xcode create all views and instantiate and alloc all objects in xib...

but, your viewController view (and subViews) are still not added in any view...

yourViewController.view.superView = nil;

so, its view has got the frame that you set in xib, but if you tell it to resize inside its superview, when you add it (e.g. with a push or an addsubview), its frame changes, but your spinner won't change its position.

calling a performSelectorOnMainThread just will call your method later, when your current thread step ahead and may have pushed your viewController.view, so, when executed, yourViewController.view.superView exists, and so view.frame has already changed.

try to move your call to

[common startActivityIndicatorOnView:self.view];

in a viewWillAppear method: at that point yourViewController.view should been already resized to fit its superView

EDIT:

@ pavel question:

after what moment yourViewController.view.superView will be not nil?

banally: when you add its view to a view. that is, firts you allocate and init it (init with a nib or via code)

something like:

yourViewControllerInstance = [[YourViewController alloc]initWithNibName:@"yourViewControllerNib" bundle:nil];

at this point the method viewDidLoad in your class is called (but yourViewController.view.superview 0 nil)

later, you usually use your new viewController, so you "push" it in the stack of a navigationController, or you just add its view to the current viewController.view... something like:

[currentViewController.view addSubview:yourViewController.view];

after this line, as you may imagine, yourViewController.view.superView = currentViewController.view, and the method viewWillAppear of yourViewController is called, so you can use superView inside it.

Notice that at this point your viewController.view is still not visible on screen, so you can adjust sizes, move or add views here without users see any changes.

after this, yourViewController will show, and at the end, and the method viewDidAppear of yourViewController is called (for any other code, in case)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top