我创建了由三个点构成的自定义活动指示器,但该指示器无法正常工作。它必须通过以下方式工作:
什么都没有出现,一个点出现,两个点出现,三个点出现,什么都没有出现……
每个点是一个带有圆角的简单UIView,我有一个线程必须按描述的顺序显示点(也尝试计时器)。问题在于,第一个点出现后,活动指示符消失之前,什么都没有改变。
LoadingIndicator.h
#import <Foundation/Foundation.h>
@interface LoadingIndicator : NSObject
{
UIView *loadingIndicator;
UILabel *loadingLabel;
UIView *dot1;
UIView *dot2;
UIView *dot3;
}
@property (nonatomic, retain) UIView *loadingIndicator;
@property (nonatomic, retain) UILabel *loadingLabel;
@property (nonatomic, retain) UIView *dot1;
@property (nonatomic, retain) UIView *dot2;
@property (nonatomic, retain) UIView *dot3;
+ (LoadingIndicator*)getInstance;
- (UIView*)getLoadingIndicator:(BOOL)withLoadingLabel at:(CGPoint)at;
- (void)removeLoadingIndicator;
@end
@interface LoadingIndicator (Private)
- (id)init;
- (UILabel*)getLoadingLabel;
- (void)startWorking;
@end
LoadingIndicator.m
#import "LoadingIndicator.h"
#import "Utils.h"
#import <QuartzCore/QuartzCore.h>
#define LOADING_INDICATOR_WIDTH 100
#define LOADING_INDICATOR_HEIGHT 50
@implementation LoadingIndicator
@synthesize loadingIndicator;
@synthesize loadingLabel;
@synthesize dot1;
@synthesize dot2;
@synthesize dot3;
static LoadingIndicator *instance;
int numOfDots = 0;
int dotSize = 15;
int effectiveHeight;
+ (LoadingIndicator*)getInstance
{
if (instance == nil)
@synchronized(self)
{
if (instance == nil)
instance = [[self alloc ]init];
}
return instance;
}
- (UIView*)getLoadingIndicator:(BOOL)withLoadingLabel at:(CGPoint)at
{
[self removeLoadingIndicator];
loadingIndicator = [[UIView alloc] init];
self.loadingIndicator.backgroundColor = RGBA(0, 0, 0, 0.5);
self.loadingIndicator.frame = CGRectMake(at.x - LOADING_INDICATOR_WIDTH / 2,
at.y - LOADING_INDICATOR_HEIGHT / 2,
LOADING_INDICATOR_WIDTH,
LOADING_INDICATOR_HEIGHT);
[self.loadingIndicator.layer setCornerRadius:8.0];
if (withLoadingLabel == YES)
[self.loadingIndicator addSubview:[self getLoadingLabel]];
if (loadingLabel)
effectiveHeight = (self.loadingIndicator.frame.size.height - (loadingLabel.frame.origin.y + loadingLabel.frame.size.height));
else
effectiveHeight = self.loadingIndicator.frame.size.height;
int y = self.loadingIndicator.frame.size.height - effectiveHeight / 2 - dotSize / 2;
int x;
x = self.loadingIndicator.frame.size.width / 3 / 2 - dotSize / 2;
dot1.frame = CGRectMake(x, y, dotSize, dotSize);
x = self.loadingIndicator.frame.size.width / 2 - dotSize / 2;
dot2.frame = CGRectMake(x, y, dotSize, dotSize);
x = self.loadingIndicator.frame.size.width / 2 + self.loadingIndicator.frame.size.width / 3 - dotSize / 2;
dot3.frame = CGRectMake(x, y, dotSize, dotSize);
//[self startWorking];
[NSThread detachNewThreadSelector:@selector(startWorking) toTarget:self withObject:nil];
return self.loadingIndicator;
}
- (void)removeLoadingIndicator
{
if (self.loadingIndicator)
{
[self.loadingIndicator removeFromSuperview];
self.loadingIndicator = nil;
loadingLabel = nil;
}
}
@end
@implementation LoadingIndicator (Private)
-(id)init
{
if (self = [super init])
{
UIColor *dotsColor = RGB(67, 173, 72);
dot1 = [[UIView alloc] init];
dot1.backgroundColor = dotsColor;
[dot1.layer setCornerRadius:8.0];
dot2 = [[UIView alloc] init];
dot2.backgroundColor = dotsColor;
[dot2.layer setCornerRadius:8.0];
dot3 = [[UIView alloc] init];
dot3.backgroundColor = dotsColor;
[dot3.layer setCornerRadius:8.0];
}
self.loadingIndicator = nil;
return self;
}
- (UILabel*)getLoadingLabel
{
UILabel *label = [[UILabel alloc] init];
label.frame = CGRectMake(0,
5,
LOADING_INDICATOR_WIDTH,
15);
label.backgroundColor = [UIColor clearColor];
label.text = NSLocalizedString(@"LOADING", @"The data is currently loading (in capital letters)");
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.font = [UIFont systemFontOfSize:13];
loadingLabel = label;
return label;
}
- (void)startWorking
{
NSLog(@"%@\nWorker thread started.",DEBUG_PLACE);
while (self.loadingIndicator)
{
//[self performSelectorOnMainThread:@selector(updateView) withObject:nil waitUntilDone:NO modes:nil];
[self updateView];
[NSThread sleepForTimeInterval:1];
}
numOfDots = 0;
}
- (void)updateView
{
NSLog(@"%@",DEBUG_PLACE);
if (self.loadingIndicator)
{
switch (numOfDots) {
case 0:
[self.loadingIndicator addSubview:dot1];
break;
case 1:
[self.loadingIndicator addSubview:dot2];
break;
case 2:
[self.loadingIndicator addSubview:dot3];
break;
default:
[dot1 removeFromSuperview];
[dot2 removeFromSuperview];
[dot3 removeFromSuperview];
break;
}
numOfDots = (numOfDots + 1) % 4;
}
else
{
numOfDots = 0;
NSLog(@"%@\nWorker thread ended.",DEBUG_PLACE);
}
}
@end
最佳答案
您无法在后台线程中更新UI。修改您的startWorking方法,如下所示:
while (self.loadingIndicator)
{
//[self performSelectorOnMainThread:@selector(updateView) withObject:nil waitUntilDone:NO modes:nil];
dispatch_async(dispatch_get_main_queue(), ^{
[self updateView];
});
[NSThread sleepForTimeInterval:1];
}
关于ios - 自定义事件指示器不起作用( objective-c ),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20065302/