我已经创建了由三个点构建的自定义活动指示器,但它无法正常工作。它必须以下列方式工作:
什么都没有出现,出现一个点,出现两个点,出现三个点,没有出现......
每个点都是一个带圆角的简单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
答案 0 :(得分:1)
您无法在后台线程中更新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];
}