4

いくつかのコンテキストを提供しましょう。ユーザーがサーバーでホストされているいくつかのビデオを検索して表示できるようにするタブ付きアプリケーションを構築しています。各タブには、ナビゲーションバーのセグメント化されたコントロールを使用してさまざまな方法でビデオがグループ化されており、ユーザーはこれを使用してリストをさらに正確に並べ替えることができます(タイトル、日付など)。セグメント化されたコントロールで[並べ替え]を押すと、モーダルビューコントローラーに特定のタブで使用可能なオプションが表示されます。オプションが選択され、その選択が親View Controllerに中継され、サーバーでソートされたリストが呼び出されます。

ここに問題があります。サポートしたいiOS4.2では、ソートオプションを選択した後にモーダルビューがクラッシュするか、モーダルビューが閉じてすぐにもう一度表示されます。再表示される場合は、1回だけ表示され、無期限にループすることはありません。トランジションとビューのライフサイクルに関係があることは知っていますが、これを正しく理解することはできないようです。

コード:

親ビュー

-(void) segmentAction:(id)sender{
    //create a sort view and pass it a value that indicates what the options should be
    ModalSortViewController *sortView = [[ModalSortViewController alloc]    
                                        initWithNibName:nil bundle:nil sortByView:0];
    [sortView setDelegate:self];
    [sortView setModalTransitionStyle:UIModalTransitionStylePartialCurl];
    [sortView setModalPresentationStyle:UIModalPresentationFormSheet];
    [self presentModalViewController:sortView animated:YES];
}

-(void) refresh:(id)sender{
    [self fetchEntries];
}

//Delegate protocol for all tabbed table views
//Receives buttonIndex from the modal sort view
-(void)sortByButtonIndex:(int)buttonIndex{

    if(buttonIndex==1){
        //If sorting by title
        fetchURL = @"fakeURL.com/?method=iGetCategories&sortBy=category&sortByOrder=ASC";
        [self fetchEntries];
    }
    else if (buttonIndex==2){
        //If sorting by number of items
        fetchURL = @"fakeURL.com/?method=iGetCategories&sortBy=count&sortByOrder=DESC";
        [self fetchEntries];
    }
    else if(buttonIndex==0){
        //Resets sort selection to nothing
        segmentedControl.selectedSegmentIndex = -1;
    }
    [self dismissModalViewControllerAnimated:YES];
}

モーダルビュー

@synthesize delegate, option1, option2;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil sortByView:(int)_viewInt
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        sortChosen = 0;
        viewInt = _viewInt;
    }
    return self;
}

//This method is called whenever a selection on the modal view has been made.
//The button tags have been set in IB and are sent to the parent table view controller
//where a switch statement is in place to sort its data by the selection.
-(IBAction)madeSelection:(id)sender{
    sortChosen = [sender tag];
    [self.delegate sortByButtonIndex:sortChosen];
}

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];//Added after Felix pointed out that the super was not called
    switch (viewInt) {
        case CAT_FOLDERS:
            [self.option1 setTitle:@"By Category Name" forState:UIControlStateNormal];
            [self.option2 setTitle:@"By Number of Items" forState:UIControlStateNormal];
            break;

        case PRES_FOLDERS:
            [self.option1 setTitle:@"By Presenter Name" forState:UIControlStateNormal];
            [self.option2 setTitle:@"By Number of Items" forState:UIControlStateNormal];
            break;

        case MEDIA:
            [self.option1 setTitle:@"By Media Title" forState:UIControlStateNormal];
            [self.option2 setTitle:@"By Release Date" forState:UIControlStateNormal];
            break;

        default:
            break;
    }
}

クラッシュの結果:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'Attempting to begin a modal transition from <UINavigationController: 
0x139160> to <ModalSortViewController: 0x172810> while a transition is already in
progress. Wait for viewDidAppear/viewDidDisappear to know the current transition has completed'

長さについて申し訳ありません。できるだけ明確で徹底的にしたかったのです。前もって感謝します!

編集:クラッシュ/リピートが表示されるのは、sortByButtonIndex:が呼び出された場所と、ビューが閉じられたタイミングに依存しているようです。

4

2 に答える 2

2

賞金を投じてからこの時間で解決する数字!

問題は、それが原因だとは思わなかったために投稿しなかったfetchEntriesメソッドが、サーバーへの呼び出しを完了するときに、セグメント化されたコントロールの選択されたインデックスを-1に設定することでした。iOSの新しいバージョンは、-1に変更されている場合、EventValueChangedを無視しているようです。segmentAction:メソッドでセグメント化されたコントロールの-1インデックスを無視する条件を設定するだけで、機能します。

-(void) segmentAction:(id)sender{

    if(segmentedControl.selectedIndex != -1){
        //create a sort view and pass it a value that indicates what the options should be
        ModalSortViewController *sortView = [[ModalSortViewController alloc]    
                                        initWithNibName:nil bundle:nil sortByView:0];
        [sortView setDelegate:self];
        [sortView setModalTransitionStyle:UIModalTransitionStylePartialCurl];
        [sortView setModalPresentationStyle:UIModalPresentationFormSheet];
        [self presentModalViewController:sortView animated:YES];
    }

}
于 2012-04-13T21:22:40.817 に答える
1

super内から電話をかけていません-(void)viewWillAppear:(BOOL)animated

上部に次の行を追加してみてください。

[super viewWillAppear:animated];

これは、ViewControllerのスーパー実装がappearフラグを正しく設定していないことを意味している可能性があります。

于 2012-04-10T15:14:46.557 に答える