Everything in your -viewDidLoad method happens in one runloop. This means that you add and remove the activity indicator without giving the system a chance to actually draw it. The 4 seconds of sleep don't help. Those just make the runloop take longer to finish.