Pracuję nad aplikacją, w której posiadanie "szuflady" po lewej stronie byłoby bardzo korzystne. Przeprowadzam wstępne testy, aby zobaczyć, jak najlepiej to osiągnąć i mam bardzo podstawowe problemy.iOS: Przesuwanie ekranu włączania/wyłączania UIView
Moja konfiguracja
1. Używam jednego szablonu widoku aplikacji w Xcode 4.
2. do "głównego/granicznego" Zdaniem XIb, w Dodałem 2 UIViews (LeftPanel i RightPanel) i UIButton (ShowHideButton).
3. Zmieniłem kolor LeftPanel na zielony i RightPanel na niebieski, aby ułatwić widoczność.
4. Po załadowaniu widoku oba panele są widoczne, a UIButton ma tekst "Ukryj panel".
5. Po naciśnięciu przycisku, LeftPanel powinien zsunąć się z ekranu (w lewo), a RightPanel powinien się rozwinąć, aby zająć jego pierwotne miejsce oraz miejsce opuszczone przez LeftPanel.
6. W tym momencie ShowHideButton powinien zmienić swój tekst na "Pokaż panel".
7. Po ponownym naciśnięciu przycisku, LeftPanel powinien przesunąć się z powrotem na ekran (od lewej), a RightPanel powinien się zmniejszyć, aby "przywrócić" swoje pierwotne miejsce.
8. W tym momencie ShowHideButton powinien zmienić tekst z powrotem na "Ukryj panel".
Wdrażam animację przy użyciu animateWithDuration:animations:completion:
. Do tej pory ekran działa dobrze (bardzo dobrze, faktycznie).
Problem polega na tym, że kiedy próbuję przywrócić LeftPanel "wracam", otrzymuję EXC_BAD_ACCESS. Poniżej zamieściłem mój kod i przyjrzałem się temu, ale naprawdę nie widzę, do czego uzyskuję dostępu (lub czegokolwiek, co powoduje 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
jestem brakuje czegoś super podstawową? Czy ktokolwiek może pomóc?
Dzięki!
EDIT: Próbowałem 2 więcej rzeczy:
1. Problem wydaje się być związane z przystosowaniem widok off-screen na ekranie, jak wychodząc z LeftPanel off-screen daje mi taki sam problem.
2. Przechodzenie przez kod niezawodnie powoduje awarię Xcode (4 Beta for Lion). Oto szczegóły (takie same dla każdej awarii):
AWARIA ASSERTION w/SourceCache/DVTFoundation/DVTFoundation-867/Framework/Classes/FilePaths/DVTFilePath.M: 373 Dane: pusty łańcuch nie jest ważna trasa obiektu Metoda: + _filePathForParent: fileSystemRepresentation długość: allowCreation: gwintu {nazwa = (zerowy) Num = 55} wskazówki: Brak Ślad: 0 0x00000001068719a6 - [IDEAssertionHandler handleFailureInMethod: obiekt: nazwa: LineNumber: messageFormat: argumenty] (w IDEKit) 1 0x0000000105f3e324 _DVTAssertionFailureHandler (w DVTFoundation) 2 0x0000000105edd16f + [DVTFilePath _filePathForParent: fileSystemRepresentation długość: allowCreation:] (w DVTFoundation) 3 0x0000000105edcd4d + [DVTFilePath _filePathForParent: pathString:] (w DVTFoundation) 4 0x0000000105ede141 + [DVTFilePath filePathForPathStrin g:] (w DVTFoundation) 5 0x00000001064a8dde - [IDEIndex queryProviderForFile: highPriority:] (w IDEFoundation) 6 0x000000010655193b - [IDEIndex (IDEIndexQueries) symbolsMatchingName: InContext: withCurrentFileContentDictionary:] (w IDEFoundation) 7 0x000000010aca6166 __68- [IDESourceCodeEditor symbolsForExpression : inQueue: completionBlock:] _ block_invoke_01561 (w IDESourceEditor) 8 0x00007fff93fb490a _dispatch_call_block_and_release (w libdispatch.dylib) 9 0x00007fff93fb615a _dispatch_queue_drain (w libdispatch.dylib) 10 0x00007fff93fb5fb6 _dispatch_queue_invoke (w libdispatch.dylib) 11 0x00007fff93fb57b0 _dispatch_worker_thread2 (w libdispatch.dylib) 12 0x00007fff8bb5e3da _pthread_wqthread (in libsystem_c.dylib) 13 0x00007fff8bb5fb85 start_wqthread (w libsystem_c.dylib)
Aktualizacja: Screen Shots
panel pokazane (stan startowy)
panel ukryty (udane przejście po naciśnięciu przycisku)
Błąd: Naciśnięcie przycisku ponownie powoduje niewydolność