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される前に2〜3秒間フリーズ状態になります。ボタンクリックイベントメソッドmyThirdViewで最初に行うのはロードであるため、この場合の応答遅延は何であるかを理解できません。残りのコードは、myThirdViewをロードするコードの後に​​のみ実行されます。しかし、コードの最初の行でさえ、遅れて実行されているようです。助言がありますか?UIActionSheetmyThirdView

4

5 に答える 5

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 に答える
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 に答える
2

質問。UIActionSheetがフリーズしますか、それとも消えて3番目のビューが2〜3秒間表示されませんか?

これは、2つの問題のうちの1つが原因である可能性があります。

  1. アクションシート全体がフリーズする場合は、その3番目のビューを初期化するときに手間のかかる作業を行っているか、コアデータ、大量のアセット、または時間がかかるものを読み込んでいます。この場合、その3番目のビューをロードする方法を再フォーマットする必要があります。重い読み込みをバックグラウンドにプッシュすることをお勧めします(これは、xibに多数の画像がある場合、コードでそれらを読み込む必要がある可能性があることを意味します)。

  2. もう1つの可能性は、2番目のビューの下に3番目のビューを追加し、2番目のビューを3秒間非表示にしないことです(セレクターを遅らせて実行します)。この場合は、単に遅延を削除してください。

実行の時間を計り、コードのボトルネックを見つけるのに役立つクラスをいくつか作成しました。それらが今あなたを助けるかもしれないようです。 http://forrst.com/posts/Code_Execution_Timer_for_iOS_Development-dSJ

于 2012-06-21T19:12:17.340 に答える
1

3番目のビューの大きさはどれくらいですか。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 に答える