自定义活动指示不起作用(目标c)

时间:2013-11-19 07:07:51

标签: ios iphone objective-c

我已经创建了由三个点构建的自定义活动指示器,但它无法正常工作。它必须以下列方式工作:

什么都没有出现,出现一个点,出现两个点,出现三个点,没有出现......

每个点都是一个带圆角的简单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

1 个答案:

答案 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];
}