1

Я использовал UITapGestureRecognizer несколько раз, но в этом случае я получаю EXC_BAD_ACCESS, когда происходит крана. Я думаю, что это связано с тем фактом, что я добавляю его в вид перекрытия типа Alert. И по какой-то причине оверлейное представление не сохраняется, даже если оно отображается на экране.UITapGestureRecognizer EXC_BAD_ACCESS в автономном подклассе UIView

Я создаю представление, как это:

HelperView *testHelper = [HelperView helperWithBodyText:@"test text"]; 
[testHelper presentAtPoint:screenCenter]; 

Метод удобства в HelperView.m выглядит следующим образом:

+ (id)helperWithBodyText:(NSString*)text 
{ 
    return [[self alloc] initWithFrame:CGRectZero bodyText:text]; 
} 

И остальная часть кода выглядит следующим образом:

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     self.container = [[AGWindowView alloc] initAndAddToKeyWindow]; 
     self.container.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscapeRight; 

     self.overlay = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; 
     self.overlay.backgroundColor = [UIColor redColor]; 
     self.overlay.alpha = 0.6; 
     [self.container addSubviewAndFillBounds:self.overlay]; //this fills the screen with a transparent red color, for testing 

     UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissMe:)]; 
     [self.overlay addGestureRecognizer:tap]; //I want to dismiss the whole view if the overlay is tapped 

     self.content = [[UIView alloc] initWithFrame:CGRectZero]; 
    } 
    return self; 
} 

- (id)initWithFrame:(CGRect)frame bodyText:(NSString*)bodyText 
{ 
    self = [self initWithFrame:frame]; 
    if (self) { 

     //TEST frame 
     self.content.frame = CGRectMake(0, 0, 217, 134); 

     // Initialization code 
     UIImage *bgImage = [[UIImage imageNamed:@"helper-bg"] 
           resizableImageWithCapInsets:UIEdgeInsetsMake(30, 28, 20, 20)]; 
     UIImageView *bgImgView = [[UIImageView alloc] initWithImage:bgImage]; 
     bgImgView.bounds = self.content.frame; 
     [self.content addSubview:bgImgView]; 

} 
    return self; 
} 

- (void)presentAtPoint:(CGPoint)loc 
{ 
    CGPoint newPoint = [self.container convertPoint:loc toView:self.container]; 

    self.content.center = newPoint; 
    [self.container addSubview:self.content]; 

} 


- (void)dismissMe:(UITapGestureRecognizer*)recognizer 
{ 
    //this never happens - I get EXC_BAD_ACCESS when I tap the overlay 
} 

ответ

1

HelperView - это не представление, которое отображается, и оно не сохраняется, но вы используете в качестве цели f или распознавателя жестов. Свойство AGWindowView «контейнер» становится отображаемым и сохраняется его супервизором. Ваш код нуждается в рефакторинге, так как у вас есть этот вид HelperView, который никогда не отображает ничего, но если вы хотите, чтобы он работал так, вам нужно сохранить HelperView, чтобы он автоматически не освобождался. Вы можете сделать это, назначив ему сильную переменную экземпляра.

+0

Благодарим за информацию. Вот что я понял. Но я хочу, чтобы этот HelperView был создан, когда мне это нужно, и я не хочу, чтобы каждый контроллер представления требовал наличия для него сильной переменной экземпляра. Например, UIAlertView не требует сильной переменной экземпляра. Как я могу сохранить автономный вид? – soleil

+0

Другим примером является: https://github.com/chrismiles/CMPopTipView. Я просмотрел код, но не могу понять, как он сохраняется. – soleil

+0

Измените '[self.container addSubview: self.content]' 'быть' [self.container addSubview: self] ', и все будет хорошо, кроме утечки памяти. –