2014-12-11 1 views
0

enter image description here -------->enter image description hereКак отключить UIView, когда одно из его подзонов оживляет?

Я пытаюсь создать пользовательский UIActivityIndicatorView. Пользовательский вид должен вести себя точно так же, как и стандартный вид, за исключением того, что изображение, которое оно вращается, выглядит по-другому. Я заметил, что мое настраиваемое представление не освобождает, когда он удаляется из его надтаблицы в следующем коде теста:

ActivityIndicatorCustomView* v = [[ActivityIndicatorCustomView alloc] initWithFrame:CGRectMake(50.0f, 50.0f, 100.0f, 100.0f)]; 
[[UIApplication sharedApplication].keyWindow addSubview:v]; 
[v removeFromSuperview]; 

Виновником является анимация блока, потому что, когда она закомментирована, dealloc будет называться. Я считаю, что это цикл сохранения, но я не вижу, как решить проблему.

ActivityIndicatorCustomView.h

#import <UIKit/UIKit.h> 

@interface ActivityIndicatorCustomView : UIView 

@property(nonatomic, assign, readonly) BOOL isAnimating; 

- (void)startAnimating; 
- (void)stopAnimating; 

@end 

ActivityIndicatorCustomView.m

static const NSTimeInterval ANIMATION_PERIOD_HALF_LIFE = 1.0f; 

#import "ActivityIndicatorCustomView.h" 

@interface ActivityIndicatorCustomView() 

@property(nonatomic, strong) UIImageView* imageView; 
@property(nonatomic, assign, readwrite) BOOL isAnimating; 

- (void)animateWithTransform:(CGAffineTransform)transform; 

@end 

@implementation ActivityIndicatorCustomView 

#pragma mark NSObject 

- (void)dealloc 
{ 
    NSLog(@"dealloc"); 
} 

#pragma mark UIView 

- (id)initWithFrame:(CGRect)frame 
{ 
    if (self = [super initWithFrame:frame]) { 
     self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"activityIndicatorCustom"]]; 
     self.imageView.frame = self.bounds; 
     [self addSubview:self.imageView]; 
    } 

    return self; 
} 

- (void)didMoveToSuperview 
{ 
    if (!self.hidden && self.superview != nil) { 
     [self startAnimating]; 
    } 
} 

- (void)willMoveToSuperview:(UIView *)newSuperview 
{  
    if (newSuperview == nil) { 
     [self stopAnimating]; 
    } 
} 

- (void)setHidden:(BOOL)hidden 
{ 
    if (hidden) { 
     [self stopAnimating]; 
    } else if (self.superview != nil) { 
     [self startAnimating]; 
    } 

    [super setHidden:hidden]; 
} 

#pragma mark ActivityIndicatorCustomView 

- (void)startAnimating 
{ 
    if (self.isAnimating) { 
     return; 
    } 

    self.isAnimating = YES; 
    [self animateWithTransform:CGAffineTransformMakeRotation((CGFloat)M_PI)]; 
} 

- (void)stopAnimating 
{ 
    [self.imageView.layer removeAllAnimations]; 
    self.isAnimating = NO; 
} 

#pragma mark() 

- (void)animateWithTransform:(CGAffineTransform)transform 
{ 
    // Must split the animation into two semi-circles. If 
    // you attempt to rotate a full circle, nothing will 
    // happen. 
    __block ActivityIndicatorCustomView* weakSelf = self; 

    [UIView 
     animateWithDuration:ANIMATION_PERIOD_HALF_LIFE 
     delay:0.0 
     options:UIViewAnimationOptionCurveLinear 
     animations:^{ 
      weakSelf.imageView.transform = transform; 
     } completion:^(BOOL finished) { 
      [weakSelf animateWithTransform:CGAffineTransformIsIdentity(transform) 
       ? CGAffineTransformMakeRotation((CGFloat)M_PI) 
       : CGAffineTransformIdentity 
      ]; 
     } 
    ]; 
} 

@end 

ответ

2

Я следовал bad tutorial на сохранение циклов в блоках. Он сказал мне сделать

__block MyViewController *weakSelf = self; 

Это неправильно. Чтобы создать слабую ссылку, я должен это сделать:

__weak ActivityIndicatorCustomView* weakSelf = self; 

[UIView 
    animateWithDuration:ANIMATION_PERIOD_HALF_LIFE 
    delay:0.0 
    options:UIViewAnimationOptionCurveLinear 
    animations:^{ 
     weakSelf.imageView.transform = transform; 
    } completion:^(BOOL finished) { 
     [weakSelf animateWithTransform:CGAffineTransformIsIdentity(transform) 
      ? CGAffineTransformMakeRotation((CGFloat)M_PI) 
      : CGAffineTransformIdentity 
     ]; 
    } 
]; 
+1

Под ручным подсчетом ссылок '__block' не сохранялся. В ARC это так. –

+0

Учебное пособие опубликовано 11 января 2012 года. Думаю, это было до времени ARC. – Pwner

0

Я думаю, что это происходит потому, что вы по-прежнему анимации (и сохранить self в следующем [самоуправления animateWithTransform:] вызов) в блок завершения. Попробуйте, например, проверка на надтаблицы, чтобы решить, следует ли продолжать анимировать:

completion:^(BOOL finished) { 
     if (self.superview) { 
      [self animateWithTransform:CGAffineTransformIsIdentity(transform) 
       ? CGAffineTransformMakeRotation((CGFloat)M_PI) 
       : CGAffineTransformIdentity 
      ]; 
     } 
    } 
Смежные вопросы