6

我正在创建一个UIActionSheeton actionSheet:clickedButtonAtIndex 委托方法。

- (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];

    }

UIActionSheet我以与上述完全相同的方法处理此点击事件。

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];

    }
}

我面临的问题是,UIActionSheet需要太多时间来响应。当我点击UIActionSheet按钮时,它在myThirdView加载前处于冻结状态 2 或 3 秒。我无法理解,这种情况下的响应延迟是什么,因为我在UIActionSheet按钮单击事件方法中做的第一件事就是加载myThirdView。其余代码仅在加载 myThirdView 的代码之后执行。但即使是第一行代码似乎也会在延迟后执行。有什么建议么?

4

5 回答 5

3

用户界面操作在主线程中运行,并且仅在您的方法结束时发生。因此,MyThirdView在其他指令完成之前不会出现。我唯一能想到的就是延迟:

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

如果您正在做任何繁重的计算或净连接,那肯定是原因。

OTOH,我认为您最好修改该行:

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

如果要模拟按钮触摸动作。

于 2012-06-16T13:12:56.483 回答
3

这也许是由于这个

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

制作其他方法并在该方法中执行此操作。像这样

[self viewRemover];

并在 viewRemover

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

}

所以你的代码现在会是这样的

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];

    }
}
于 2012-06-14T09:33:19.787 回答
2

问题。UIActionSheet 是否冻结,或者它是否消失并且第三个视图在 2-3 秒内不可见?

这可能是由于 2 个问题中的 1 个。

  1. 如果整个操作表冻结,那么当您初始化第三个视图时,您正在做一些繁重的工作,您正在加载一些核心数据,或者大量资产,或者需要很长时间的东西。如果是这种情况,您需要重新格式化加载第三个视图的方式。我建议将任何繁重的负载推到后台(这意味着如果您的 xib 中有很多图像,您可能需要在代码中加载它们)。

  2. 另一种可能性是,您要在第二个视图下方添加第三个视图,然后在 3 秒内不隐藏第二个视图(通过延迟执行选择器来完成)。如果是这种情况,只需删除延迟。

我做了几个类来帮助我计时执行并找到我的代码中的瓶颈,现在它们似乎可以帮助你。 http://forrst.com/posts/Code_Execution_Timer_for_iOS_Development-dSJ

于 2012-06-21T19:12:17.340 回答
1

你的第三个视图有多大。如果 nib 文件需要加载太多,您可能会等待很多事情发生,此外,如果您必须更改一些 UI 元素并阻塞 UI 线程,您将拖拉您的应用程序,直到发生超时并且应用程序将转移有些东西要补偿。。

我采取的路线是 dispatch_async 和 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.
    });

});

在 UI 线程中做太多事情会暂停执行堆积在队列中的事情。将所有代码发送到后台线程并仅在您需要更改 UI 时才跳到 UI 线程,这是编写 iPhone 应用程序的更好且响应速度更快的方式。

我希望这有帮助 :)

于 2012-06-22T22:39:51.617 回答
0

在 Swift 4 中:我用这个块包装了代码

DispatchQueue.main.async {

// your code to show action sheet.

}

例如

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)

        }
于 2019-05-11T06:37:47.423 回答