------>
我正在尝试创建自定义 UIActivityIndicatorView .自定义 View 的行为应该与标准 View 完全相同,除了它旋转的图像看起来不同。我注意到在以下测试代码中,当我的自定义 View 从其 super View 中删除时,它不会被释放:
ActivityIndicatorCustomView* v = [[ActivityIndicatorCustomView alloc] initWithFrame:CGRectMake(50.0f, 50.0f, 100.0f, 100.0f)];
[[UIApplication sharedApplication].keyWindow addSubview:v];
[v removeFromSuperview];
罪魁祸首是动画 block ,因为当它被注释掉时,会调用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
最佳答案
我正在关注 bad tutorial在 block 中保留循环。它告诉我要做
__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
];
}
];
关于ios - 如何在其 subview 之一正在动画时释放 UIView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27431483/