2011-07-29 17 views
10

左側に「引き出し」があると非常に便利なアプリに取り組んでいます。私はこれをどのようにして達成するのかを見極めるためにいくつかの初期テストをしています。私はいくつかの非常に基本的な問題を抱えています。iOS:UIViewのオン/オフ画面をスライディング

私のセットアップ私はXIBの「メイン/ボーダー」ビューにXcodeの4
2の単一ビューのアプリケーションテンプレートを使用しています

1.、私は2つのUIViews(LeftPanelとRightPanel)を追加しましたUIButton(ShowHideButton)があります。
3.わかりやすいように、LeftPanelの緑とRightPanelの色を塗りました。
4.ビューが読み込まれると、両方のパネルが表示され、UIButtonのテキストは「パネルの非表示」になります。
5.ボタンを押すと、LeftPanelが画面(左)からスライドし、RightPanelが元のスペースとLeftPanelによって空けられたスペースを占めるように拡張されます。
6.この時点で、ShowHideButtonはそのテキストを「Show Panel」に変更する必要があります。
7.もう一度ボタンを押すと、LeftPanelが画面上(左から)にスライドし、RightPanelが縮小して元のスペースに戻します。
8.この時点で、ShowHideButtonはテキストを「Hide Panel」に戻す必要があります。

animateWithDuration:animations:completion:を使用してアニメーションを実装しています。これまでのところ、遷移オフ画面は正常に動作しています(非常に、実際に)。

LeftPanelを「戻す」ことを試みると、EXC_BAD_ACCESSが表示されます。私は下に自分のコードを掲載しましたが、私はそれを見ましたが、実際に私がアクセスしているものがリリースされているかどうか(またはEXC_BAD_ACCESSを引き起こしているもの)は見えません。

DrawerTestingViewController.h 
#import <UIKit/UIKit.h> 

typedef enum { 
    kHidden, 
    kShown 
} PanelState; 

@interface DrawerTestingViewController : UIViewController { 

    PanelState currentState; 

    UIButton *showHideButton; 

    UIView  *leftPanel; 
    UIView  *rightPanel; 
} 

@property (assign, nonatomic)   PanelState CurrentState; 

@property (strong, nonatomic) IBOutlet UIButton  *ShowHideButton; 

@property (strong, nonatomic) IBOutlet UIView  *LeftPanel; 
@property (strong, nonatomic) IBOutlet UIView  *RightPanel; 

- (IBAction)showHidePressed:(id)sender; 

@end 


DrawerTestingViewController.m 
#import "DrawerTestingViewController.h" 

@implementation DrawerTestingViewController 

@synthesize CurrentState = currentState; 
@synthesize LeftPanel  = leftPanel; 
@synthesize RightPanel  = rightPanel; 
@synthesize ShowHideButton = showHideButton; 

#pragma mark - My Methods 

- (IBAction)showHidePressed:(id)sender 
{ 
    switch ([self CurrentState]) { 
     case kShown: 
      // Hide the panel and change the button's text 
      // 1. Hide the panel 
      [UIView animateWithDuration:0.5 
       animations:^{ 
       // b. Move left panel from (0, 0, w, h) to (-w, 0, w, h) 
       CGRect currLeftPanelRect = [[self LeftPanel] frame]; 
       currLeftPanelRect.origin.x = -1 * currLeftPanelRect.size.width; 
       [[self LeftPanel] setFrame:currLeftPanelRect]; 
       // c. Expand right panel from (x, 0, w, h) to (0, 0, w + x, h) 
       CGRect currRightPanelRect = [[self RightPanel] frame]; 
       currRightPanelRect.origin.x = 0; 
       currRightPanelRect.size.width += currLeftPanelRect.size.width; 
       [[self RightPanel] setFrame:currRightPanelRect];} 
       completion:NULL]; 
      // 2. Change the button's text 
      [[self ShowHideButton] setTitle:@"Show Panel" forState:UIControlStateNormal]; 
      // 3. Flip [self CurrentState] 
      [self setCurrentState:kHidden]; 
      break; 
     case kHidden: 
      // Show the panel and change the button's text 
      // 1. Show the panel 
      [UIView animateWithDuration:0.5 
       animations:^{ 
       // b. Move left panel from (-w, 0, w, h) to (0, 0, w, h) 
       CGRect currLeftPanelRect = [[self LeftPanel] frame]; 
       currLeftPanelRect.origin.x = 0; 
       [[self LeftPanel] setFrame:currLeftPanelRect]; 
       // c. Expand right panel from (0, 0, w, h) to (leftWidth, 0, w - leftWidth, h) 
       CGRect currRightPanelRect = [[self RightPanel] frame]; 
       currRightPanelRect.origin.x = currLeftPanelRect.size.width; 
       currRightPanelRect.size.width -= currLeftPanelRect.size.width; 
       [[self RightPanel] setFrame:currRightPanelRect];} 
       completion:NULL]; 
      // 2. Change the button's text 
      [[self ShowHideButton] setTitle:@"Hide Panel" forState:UIControlStateNormal]; 
      // 3. Flip [self CurrentState] 
      [self setCurrentState:kShown]; 
      break; 
     default: 
      break; 
    } 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self setCurrentState:kShown]; 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    switch ([self CurrentState]) { 
     case kShown: 
      [[self ShowHideButton] setTitle:@"Hide Panel" forState:UIControlStateNormal]; 
      break; 
     case kHidden: 
      [[self ShowHideButton] setTitle:@"Show Panel" forState:UIControlStateNormal]; 
      break; 
     default: 
      break; 
    } 
} 

@end 

私は超基本的な何かが足りないのですか?誰でも助けることができますか?

ありがとうございました!

編集: 私が試した2つの以上のもの:
1の問題は、私に与えオフスクリーンLeftPanelで始まるように、画面上のオフスクリーンビューをもたらすことに関係しているように見えます同じ問題。
2.コードをステップ実行すると、確実にXcode(4 Beta for Lion)がクラッシュします。詳細は次のとおりです(すべてのクラッシュで同じ):/ SourceCache/DVTFoundation/DVTFoundation-867/Framework/Classes/FilePaths/DVTFilePathのASSERTION FAILUREが発生します。M:373の 詳細: バックトレースなし: 方法:+ _filePathForParent:fileSystemRepresentation:長さ:allowCreation: スレッド:{名前=(NULL)、NUM = 55} ヒント空の文字列が有効なパス オブジェクトない 0 0x00000001068719a6 - [IDEAssertionHandler handleFailureInMethod:目的:ファイル名:行番号:のMessageFormat:引数:(DVTFoundationで) 1 0x0000000105f3e324 _DVTAssertionFailureHandler 2 0x0000000105edd16f +(IDEKitで):fileSystemRepresentation:長さ:allowCreation:DVTFilePath _filePathForParent(DVTFoundationで) 3 0x0000000105edcd4d + [DVTFilePath _filePathForParent:pathString:](DVTFoundation内) 4 0x0000000105ede141 + [DVTFilePath filePathForPathStrin G:] 0x00000001064a8dde 5 (DVTFoundationで) - [IDEIndex queryProviderForFile:highPriorityを:] 6 0x000000010655193b(IDEFoundationで) - [IDEIndex(IDEIndexQueries)symbolsMatchingName:inContext:withCurrentFileContentDictionary:(IDEFoundationで) 7 0x000000010aca6166 __68- [IDESourceCodeEditor symbolsForExpression :inQueue:completionBlock:(libdispatch.dylib中)] _ block_invoke_01561(libdispatch.dylib中)(IDESourceEditorで) 8 0x00007fff93fb490aの_dispatch_call_block_and_release(libdispatch.dylibで) 9 0x00007fff93fb615aの_dispatch_queue_drain 10 0x00007fff93fb5fb6 _dispatch_queue_invoke 11 0x00007fff93fb57b0 _dispatch_worker_thread2(libdispatch.dylibで) 12 0x00007fff8bb5e3da _pthread_wqthread(libsystem_c.dylib内) 13 0x00007fff8bb5fb85(libsystem_c.dylib中)start_wqthread

更新:示された画面ショット
は、パネル(起動状態) Panel Shown
パネル隠し(ボタンを押した後に成功した移行) Panel Hidden
エラー:もう一度ボタンを押すと、失敗 Error


答えて

11

遊ん後原因私はブロックについて何かを誤解しない限り、私のコードは間違いではないという結論に至りました。デバッグで私のコードをステップ実行すると、期待通りの答えが得られましたが、アニメーションブロックの終わりと完了ブロックの始まりの間にEXC_BAD_ACCESSがポップアップしていました。

とにかく、どこにアイデアがあるのか​​分かりませんが、私はアニメーションブロックの外で(フレームを変更するための)数学的計算を試してみたいと思っていました。

ITは働いた!

ので、さらに苦もなく、ここで私が何を望むかの作業コードは次のとおりです。

- (IBAction)showHidePressed:(id)sender 
{ 
    switch ([self CurrentState]) { 
     case kShown: 
     { 
      // Hide the panel and change the button's text 
      CGRect currLeftPanelRect = [[self LeftPanel] frame]; 
      currLeftPanelRect.origin.x -= currLeftPanelRect.size.width/2; 
      CGRect currRightPanelRect = [[self RightPanel] frame]; 
      currRightPanelRect.origin.x = 0; 
      currRightPanelRect.size.width += currLeftPanelRect.size.width; 
      // 1. Hide the panel 
      [UIView animateWithDuration:0.5 
       animations:^{ 
       // b. Move left panel from (0, 0, w, h) to (-w, 0, w, h) 
       [[self LeftPanel] setFrame:currLeftPanelRect]; 
       // c. Expand right panel from (x, 0, w, h) to (0, 0, w + x, h) 
       [[self RightPanel] setFrame:currRightPanelRect]; 
       } 
       completion:^(BOOL finished){ if(finished) { 
       [[self ShowHideButton] setTitle:@"Show Panel" forState:UIControlStateNormal]; 
       [self setCurrentState:kHidden]; 
       } 
       }]; 
     }    
      break; 
     case kHidden: 
     { 
      // Show the panel and change the button's text 
      // 1. Show the panel 
      [UIView animateWithDuration:0.5 
       animations:^{ 
       // b. Move left panel from (-w, 0, w, h) to (0, 0, w, h) 
       CGRect currLeftPanelRect = [[self LeftPanel] frame]; 
       currLeftPanelRect.origin.x += currLeftPanelRect.size.width/2; 
       [[self LeftPanel] setFrame:currLeftPanelRect]; 
       // c. Expand right panel from (0, 0, w, h) to (leftWidth, 0, w - leftWidth, h) 
       CGRect currRightPanelRect = [[self RightPanel] frame]; 
       currRightPanelRect.origin.x = currLeftPanelRect.size.width; 
       currRightPanelRect.size.width -= currLeftPanelRect.size.width; 
       [[self RightPanel] setFrame:currRightPanelRect]; 
       } 
       completion:^(BOOL finished){ if(finished) { 
       [[self ShowHideButton] setTitle:@"Hide Panel" forState:UIControlStateNormal]; 
       [self setCurrentState:kShown]; 
       } 
       }]; 
     } 
      break; 
     default: 
      break; 
    } 
} 
0

私はあなたのクラッシュは、あなたがメインスレッドを置くたびに、UIKitにして得ることができる不確定な状態の問題としなければならなかったと思います負荷がかかっているか、ビュー遷移の途中です。アニメーションブロック内の数値計算の値をブロック外で比較すると、それらはUIViewモデルにアクセスするためのさまざまなコンテキストになります。そのため、メモリエラーが発生したアニメーションコンテキストには驚かないでしょう。