簡體   English   中英

UITapGestureRecognizer在關閉viewController后導致崩潰

[英]UITapGestureRecognizer causes crash after dismissing viewController

試圖將UITapGestureRecognizer實現為表單模態UITapGestureRecognizer 如果用戶觸摸了表單外,則應該關閉表單,這樣代碼就可以正常工作。

問題是,如果我手動關閉表單並嘗試觸摸任何角度,它仍然嘗試調用UITapGestureRecognizer方法,導致應用程序崩潰。

Error ::
    -[xxxxView handleTapBehind:]: message sent to deallocated instance



-(void)done
{
    [self.navigationController popViewControllerAnimated:YES];
        //send notification that folder has been created
        [[NSNotificationCenter defaultCenter] postNotificationName:@"refreshDetails" object:nil];
}
-(void)viewDidAppear:(BOOL)animated
{
    // gesture recognizer to cancel screen
    UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapBehind:)];
    [recognizer setNumberOfTapsRequired:1];
    recognizer.cancelsTouchesInView = NO; //So the user can still interact with controls in the modal view
    [self.view.window addGestureRecognizer:recognizer];

}

- (void)handleTapBehind:(UITapGestureRecognizer *)sender
{
    if (sender.state == UIGestureRecognizerStateEnded)
    {
        CGPoint location = [sender locationInView:nil]; //Passing nil gives us coordinates in the window

        //Then we convert the tap's location into the local view's coordinate system, and test to see if it's in or outside. If outside, dismiss the view.

        if (![self.view pointInside:[self.view convertPoint:location fromView:self.view.window] withEvent:nil])
        {
            // Remove the recognizer first so it's view.window is valid.
            [self.view.window removeGestureRecognizer:sender];
            [self dismissModalViewControllerAnimated:YES];
        }
    }
}

為什么在我關閉viewcontroller后仍會調用handleTapBehind: 我怎樣才能解決這個問題?

您將手勢識別器添加到窗口:

[self.view.window addGestureRecognizer:recognizer];

並將目標設置為您的控制器;

因此,當您的控制器關閉時-它已釋放,但手勢識別器仍然有效。 並在觸發時嘗試將操作發送到您的控制器,而該控制器尚不存在。

因此,您應該在控制器的視圖中添加識別器,或者在viewWillDissaper方法中將其刪除。

嘗試使用手勢識別器的委托方法,在手動關閉vc並在shouldReceiveTouch中放置一個標志:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
   if(flag)
   {
      return NO;
   }
   return YES;
}

不要忘記將委托設置為當前的視圖控制器。 您現在還可以刪除[self.view.window removeGestureRecognizer:sender]行;

我想從@mikhail的答案中添加代碼

 (UITapGestureRecognizer *)senderTap

-(void)viewWillDisappear:(BOOL)animated{

     [self.view.window removeGestureRecognizer:senderTap];
}

在我的代碼中,當調用ViewDidAppear時,我通過選擇器方法捕獲了UITapGestureRecognizer(發送者)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM