手势在UIScrollView的子视图中触发异常

时间:2014-07-15 16:38:08

标签: ios uiscrollview uigesturerecognizer

新手iOS程序员在这里,很抱歉,如果我错过了一些简单的东西,但是......

我有一个名为 LVSTSPMasterViewController 的UIViewController类,其视图是在IB中构建的。该视图包含一个UIScrollView(在IB中添加),该滚动视图的子视图类型为 LVSTSPView LVSTSPView 有一个 LVSTSPViewController 类型的控制器。

我想回复 LVSTSPView 中的触摸,因此我将手势识别器添加到 LVSTSPViewController.m 。当我执行手势(例如,长按)时,代码在 main.m 中崩溃并显示消息“EXC_BAD_ACCESS(code = 1,address = ...)”。

相关代码:

LVSAppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    // Get pointer to app bundle
    NSBundle *appBundle = [NSBundle mainBundle];

    // Get xib file
    LVSTSPMasterViewController *tspmvc = [[LVSTSPMasterViewController alloc] initWithNibName:@"LVSTSPMasterViewController" bundle:appBundle];

    self.window.rootViewController = tspmvc;

    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

LVSMasterViewController.m

@interface LVSTSPMasterViewController () <UIScrollViewDelegate>

// IBOutlet declarations

@property (nonatomic, weak) IBOutlet UIScrollView *TSPScrollView;

// Pointers for convenience

@property (strong, nonatomic) LVSTSPView *TSPView;

@end

@implementation LVSTSPMasterViewController
- (void)viewDidLoad
{
    // Create LVSTSPViewController
    LVSTSPViewController *tspvc = [[LVSTSPViewController alloc] init];

    // Set up pointer to LVSTSPView
    self.TSPView = (LVSTSPView *)tspvc.view;

    // Set frame of LVSTSPView
    self.TSPView.frame = self.TSPScrollView.bounds;

    // Set tspvc's view as subview of TSPScrollView
    [self.TSPScrollView addSubview:tspvc.view];

    // Set up scroll view
    self.TSPScrollView.pagingEnabled = NO;
    self.TSPScrollView.contentSize = self.TSPView.frame.size;
    self.TSPScrollView.minimumZoomScale = 1.0;
    self.TSPScrollView.maximumZoomScale = 3.0;

    // Set scroll view's delegate property
    self.TSPScrollView.delegate = self;
}

LVSTSPViewController.m

- (void)loadView
{
    // Create view
    LVSTSPView *view = [[LVSTSPView alloc] initWithFrame:CGRectZero];
    self.view = view;

    // Long-press recognizer
    UILongPressGestureRecognizer *pressRecognizer =
        [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
    [self.view addGestureRecognizer:pressRecognizer];
}

- (void)longPress:(UIGestureRecognizer *)gr
{
    NSLog(@"longPress:");

}

另一个注意事项:如果我在 LVSTSPMasterViewController.m viewDidLoad:中设置手势识别器,就像这样 -

UILongPressGestureRecognizer *pressRecognizer =
    [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[self.TSPView addGestureRecognizer:pressRecognizer];

- (当然将longPress:添加到 LVSTSPMasterViewController.m ),然后就可以了。但这似乎不是正确的方法,因为 LVSTSPMasterViewController 不是 LVSTSPView 的视图控制器。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

您的视图控制器LVSTSPViewController不会保留在任何位置,换句话说,您的主视图控制器需要保留它。
LVSMasterViewController.m 中,将代码更改为

@implementation LVSTSPMasterViewController
{
   LVSTSPViewController *tspvc;//creates strong reference to self(LVSTSPMasterViewController)
}

- (void)viewDidLoad
{
  [super viewDidLoad];
  // Do any additional setup after loading the view from its nib.
  tspvc = [[LVSTSPViewController alloc] init];

  // Set up pointer to LVSTSPView
  self.TSPView = (LVSTSPView *)tspvc.view;

  // Set frame of LVSTSPView
  self.TSPView.frame = self.TSPScrollView.bounds;

  // Set tspvc's view as subview of TSPScrollView
  [self.TSPScrollView addSubview:tspvc.view];

  // Set up scroll view
  self.TSPScrollView.pagingEnabled = NO;
  self.TSPScrollView.contentSize = self.TSPView.frame.size;
  self.TSPScrollView.minimumZoomScale = 1.0;
  self.TSPScrollView.maximumZoomScale = 3.0;

  // Set scroll view's delegate property
  self.TSPScrollView.delegate = self;
}

也始终先在 viewDidLoad 方法中调用 [super viewDidLoad] 。我建议在Apple文档中阅读有关视图和视图控制器的更多信息。您不一定需要每个视图都有一个视图控制器。这一切都取决于你的具体情况。一个视图控制器可以管理多个视图。