UIActionSheet takes a long time to respond

I create a UIActionSheet in the actionSheet: clickedButtonAtIndex delegate method.

 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex if(buttonIndex == 1){ [self.myFirstView removeFromSuperview]; if (!self.mySecondView) { [[NSBundle mainBundle] loadNibNamed:@"MySecondView" owner:self options:nil]; } [self.mySecondView setFrame:CGRectMake(0, 0, 320, 480)]; [[UIApplication sharedApplication].keyWindow addSubview: self.mySecondView]; UIActionSheet * action = [[UIActionSheet alloc]initWithTitle:@"" delegate:self cancelButtonTitle: nil destructiveButtonTitle: deleteContacts otherButtonTitles: cancel, nil]; action.tag = 102; [action showInView:self.view]; [action release]; } 

I am handling the click event of this UIActionSheet in the same method as above.

 if(actionSheet.tag == 102){ if(buttonIndex == 0){ if([[NSBundle mainBundle] loadNibNamed:@"MyThirdView" owner:self options:nil]) { [self.myThirdView setFrame:CGRectMake(0, 0, 320, 480)]; [[UIApplication sharedApplication].keyWindow addSubview:self.myThirdView]; } [self.mySecondView removeFromSuperview]; [self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target]; [self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0]; } } 

The problem I am facing is that the UIActionSheet takes too long to respond. When I click on the UIActionSheet button, it is frozen for 2 or 3 seconds before myThirdView loads. I cannot understand that the response delay in this case, as the first thing I do in the UIActionSheet click event method, is to load myThirdView . The rest of the code is only executed after the code to load myThirdView. But even the first line of code seems to be executed after a delay. Any suggestions?

+6
source share
5 answers

Question. Does the UIActionSheet freeze or disappear, and the third view does not appear for 2-3 seconds?

This may be due to 1 of 2 problems.

  • If the whole action screen freezes, you make a heavy climb, when you start the third view, you load some basic data or a lot of assets or something that takes a lot of time. If so, you need to reformat HOW you load this third view. I suggest pushing any heavy load into the background (this means that if you have a lot of images in xib, you might need to load them into code).

  • Another possibility is that you add the 3rd view BELOW the second view, and then do not hide the 2nd view for 3 seconds (performed by performing a delay selector). If so, just remove the delay.

I did a couple of classes to help me complete the time and find bottlenecks in my code, it seems they can help you now. http://forrst.com/posts/Code_Execution_Timer_for_iOS_Development-dSJ

+2
source

perhaps this is due to this

 [self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0]; 

create other methods and do it in this method. like this

 [self viewRemover]; 

and in viewRemover

 -(void) viewRemover { [self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0]; } 

therefore, your code will be as it is now.

 if(actionSheet.tag == 102){ if(buttonIndex == 0){ if([[NSBundle mainBundle] loadNibNamed:@"MyThirdView" owner:self options:nil]) { [self.myThirdView setFrame:CGRectMake(0, 0, 320, 480)]; [[UIApplication sharedApplication].keyWindow addSubview:self.myThirdView]; } [self.mySecondView removeFromSuperview]; [self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target]; [self performSelectorInBackground:@selector(viewRemover) withObject:nil]; } } 
+3
source

UI actions run in the main thread and only occur when your method ends. Thus, MyThirdView will not appear until the other instructions are complete. The only thing I can understand is the delay:

 [self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target]; 

If you are doing any heavy computing or network connection, this is probably the reason.

OTOH, I think you better change this line:

 [self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton]; 

if you want to simulate a button click action.

+3
source

How big is your third opinion. if the nib file is too loaded, you can expect a lot, even if you need to change some user interface elements and block the user interface flow, you will use your application until a timeout occurs and the application shifts some things to compensate. .

the route I take with this is dispatch_async and dispatch_sync

 // This will release the UI thread which may be blocking your calls. // You can use any of the DISPATCH_QUEUE_PRIORITY_.... values to set how important this block is. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // this command will get added to the stack and return without a hitch. // the block will be run the next time the main runloop ends. dispatch_async(dispatch_get_main_queue(), ^{ // do some UI work that can happen without a hitch, and does not impact the calling block }); // this command will act much the same. but will pause the background execution // of this block until the runloop has executed this and returned. dispatch_sync(dispatch_get_main_queue(), ^{ // do some UI work that must be completed to continue. }); }); 

too much in the user interface thread pauses things that are being queued. Delivering all the code to a background thread and only switching to a user interface thread when you need to change the interface is the best and most responsive way to encode your iphone application.

Hope this helps :)

+1
source

in Swift 4: I wrapped the code with this block

 DispatchQueue.main.async { // your code to show action sheet. } 

eg

 DispatchQueue.main.async { let alert = UIAlertController(title: "Options", message: String("What do want to do?"), preferredStyle: UIAlertController.Style.actionSheet) alert.addAction(UIAlertAction(title: "Open", style: UIAlertAction.Style.default, handler: {(action:UIAlertAction!) in self.myOpen(code: self.codes[indexPath.row]) })) alert.addAction(UIAlertAction(title: "Delete", style: UIAlertAction.Style.default, handler: {(action:UIAlertAction!) in self.myDelete(indexPath: indexPath) })) alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.default, handler: {(action:UIAlertAction!) in print("Cancel") })) self.present(alert, animated: true, completion: nil) } 
0
source

Source: https://habr.com/ru/post/918072/


All Articles