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

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

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

10-14 20:40