我正在开发一个应用程序,左侧有一个“抽屉”会非常有益。我正在做一些初步测试,看看我如何最好地完成这个,我遇到了一些非常基本的问题。
我的设置
1. 我在 Xcode 4 中使用单视图应用程序模板。
2. 在 xib 的“主/边框”视图中,我添加了 2 个 UIView(LeftPanel 和 RightPanel)和一个 UIButton(ShowHideButton)。
3. 为了便于查看,我将 LeftPanel 涂成绿色,将 RightPanel 涂成蓝色。
4. 加载视图时,两个面板都是可见的,并且 UIButton 具有文本“隐藏面板”。
5. 按下按钮后,LeftPanel 应滑出屏幕(向左),RightPanel 应展开以占用其原始空间加上 LeftPanel 腾出的空间。
6. 此时,ShowHideButton 应将其文本更改为“显示面板”。
7. 再次按下按钮后,LeftPanel 应滑回屏幕(从左侧),RightPanel 应缩小以“归还”其原始空间。
8. 此时,ShowHideButton 应将其文本更改回“隐藏面板”。
我正在使用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(Lion 的 4 Beta)崩溃。以下是详细信息(每次崩溃都相同):
/SourceCache/DVTFoundation/DVTFoundation-867/Framework/Classes/FilePaths/DVTFilePath.m:373 中的断言失败详细信息:空字符串不是有效路径对象:方法:+_filePathForParent:fileSystemRepresentation:长度:allowCreation:线程:{name = (null),num = 55}提示:无回溯:0 0 0x00000001068719A6 - [IdearSertionHandler HanderFailureInmethod:filename:LineNumber:MessageFormat:参数:](在IDEKIT中)1 0x0000000105failure handler(在dvtfoundation中)2 0x0000000105edd16f + [dvtfilepath _filepathforper:filesystemrepruseentation :length:allowCreation:] (在 DVTFoundation 中) 3 0x0000000105edcd4d +[DVTFilePath _filePathForParent:pathString:] (在 DVTFoundation 中) 4 0x0000000105ede141 +[DVTFilePath filePathForPathString:] (在 DVTFoundation 中) 5 0x00000001064a8dde -[IDEIndex queryProviderFor高优先级:(在IDEFoundation)6 0x000000010655193b - [IDEIndex(IDEIndexQueries)symbolsMatchingName:inContext的:withCurrentFileContentDictionary:](在IDEFoundation)7 0x000000010aca6166 __68- [IDESourceCodeEditor symbolsForExpression:INQUEUE:completionBlock:] _ block_invoke_01561(在IDESourceEditor)8 0x00007fff93fb490a _dispatch_call_block_and_release(在libdispatch名为.dylib)9 0x00007fff93fb615a _dispatch_queue_drain(在libdispatch.dylib)10 0x00007fff93fb5fb6 _dispatch_queue_invoke(在libdispatch.dylib)11 0x00007fff93fb57b0 _dispatch_worker_thread2(在libdispatch.dylib)12 0x00007fff8bb5e3da _pthread_wqthread(在libsystem_c.dylib)13 0x00007fff8bb5fb85 start_wqthread(在libsystem_c.dylib)withCurrentFileContentDictionary:](在IDEFoundation)7 0x000000010aca6166 __68- [IDESourceCodeEditor symbolsForExpression:INQUEUE:completionBlock:] _ block_invoke_01561(在IDESourceEditor)8 0x00007fff93fb490a _dispatch_call_block_and_release(在libdispatch.dylib)9 0x00007fff93fb615a _dispatch_queue_drain(在libdispatch.dylib)10 0x00007fff93fb5fb6 _dispatch_queue_invoke(在libdispatch。 dylib)11 0x00007fff93fb57b0 _dispatch_worker_thread2(在 libdispatch.dylib 中)12 0x00007fff8bb5e3da _pthread_wqthread(在 libsystem_c.dylib 中)13 0x00007fff8bb5fb85 start_wqthread(在 libsystem_c.dylib 中)withCurrentFileContentDictionary:](在IDEFoundation)7 0x000000010aca6166 __68- [IDESourceCodeEditor symbolsForExpression:INQUEUE:completionBlock:] _ block_invoke_01561(在IDESourceEditor)8 0x00007fff93fb490a _dispatch_call_block_and_release(在libdispatch.dylib)9 0x00007fff93fb615a _dispatch_queue_drain(在libdispatch.dylib)10 0x00007fff93fb5fb6 _dispatch_queue_invoke(在libdispatch。 dylib)11 0x00007fff93fb57b0 _dispatch_worker_thread2(在 libdispatch.dylib 中)12 0x00007fff8bb5e3da _pthread_wqthread(在 libsystem_c.dylib 中)13 0x00007fff8bb5fb85 start_wqthread(在 libsystem_c.dylib 中)dylib)9 0x00007fff93fb615a _dispatch_queue_drain(在libdispatch.dylib)10 0x00007fff93fb5fb6 _dispatch_queue_invoke(在libdispatch.dylib)11 0x00007fff93fb57b0 _dispatch_worker_thread2(在libdispatch.dylib)12 0x00007fff8bb5e3da _pthread_wqthread(在libsystem_c.dylib)13 0x00007fff8bb5fb85 start_wqthread(在libsystem_c.dylib)dylib)9 0x00007fff93fb615a _dispatch_queue_drain(在libdispatch.dylib)10 0x00007fff93fb5fb6 _dispatch_queue_invoke(在libdispatch.dylib)11 0x00007fff93fb57b0 _dispatch_worker_thread2(在libdispatch.dylib)12 0x00007fff8bb5e3da _pthread_wqthread(在libsystem_c.dylib)13 0x00007fff8bb5fb85 start_wqthread(在libsystem_c.dylib)
更新:屏幕截图
面板显示(启动状态)
面板隐藏(按钮按下后成功转换)
错误:再次按下按钮导致失败