带有加载活动指示符的UITableView子类

时间:2014-10-08 17:42:51

标签: ios uitableview coding-style subclass

我的应用程序有几个UITableViews,当我提取数据来填充表格时,它们都应显示加载指示符。我正试图想出一个实现这个的聪明方法。

我是否应该将UITableView子类化,默认情况下使用另一个具有活动指示符和标签的视图覆盖tableView?然后我可以在我的故事板中分配每个UITableView子类。

但我有两个问题:

  1. 我读过UITableView的子类不是一个好主意吗?这样做有更好的范例吗?
  2. 如果我是UITableView的子类,我如何开始以编程方式添加自定义视图?

2 个答案:

答案 0 :(得分:1)

您可以使用我的解决方案:

UIViewsIndicatorsPull.h

#import <Foundation/Foundation.h>    

@interface UIViewsIndicatorContainer : NSObject

@property (nonatomic, weak) UIView *view;
@property (nonatomic, strong)UIActivityIndicatorView *indicator;

@end


@interface UIViewsIndicatorsPull : NSObject

+ (instancetype)instance;

- (UIActivityIndicatorView*)indicatorForViewObject:(UIView*)object;
- (UIActivityIndicatorView*)indicatorForViewObject:(UIView*)object style:(UIActivityIndicatorViewStyle)style;
- (void)removeIndicatorForViewObject:(UIView*)object;

@end

UIViewsIndicatorsPull.m

#import "UIViewsIndicatorsPull.h"

@implementation UIViewsIndicatorsPull
{
    NSMutableArray *indicators;
}

+ (instancetype)instance
{
    static UIViewsIndicatorsPull *sharedInstance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [UIViewsIndicatorsPull new];
    });

    return sharedInstance;
}

- (UIActivityIndicatorView*)indicatorForViewObject:(UIView*)object
{
    return [self indicatorForViewObject:object style:UIActivityIndicatorViewStyleGray];
}

- (UIActivityIndicatorView*)indicatorForViewObject:(UIView*)object style:(UIActivityIndicatorViewStyle)style
{
    if (indicators == nil) {
        indicators = [NSMutableArray array];
    }        
    UIActivityIndicatorView *result;
    for (UIViewsIndicatorContainer *entity in indicators){
        if (entity.view == object) {
            result = (UIActivityIndicatorView*)entity.indicator;
            break;
        }
    }

    if (result == nil) {
        result = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:style];

        [object addSubview:result];

        UIViewsIndicatorContainer *entity = [[UIViewsIndicatorContainer alloc] init];
        entity.view = object;
        entity.indicator = (UIActivityIndicatorView*)result;

        [indicators addObject:entity];
    }

    return result;
}

- (void)removeIndicatorForViewObject:(UIView*)object
{
    for (UIViewsIndicatorContainer *entity in indicators){
        if (entity.view == object) {
            UIActivityIndicatorView *indicator = entity.indicator;
            [indicator stopAnimating];
            [indicator removeFromSuperview];

            [indicators removeObject:entity];
            break;
        }
    }
}    
@end

@implementation UIViewsIndicatorContainer

@end

的UIView + Additions.h

#import <UIKit/UIKit.h>
#import "UIViewsIndicatorsPull.h"

#define UIViewAutoresizingAll UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth

@interface UIView (Additions)

//process indicator
- (void)showProcessIndicator;
- (void)showProcessIndicatorWithStyle:(UIActivityIndicatorViewStyle)style;
- (void)showProcessIndicatorWithAlignment:(UIViewContentMode)mode;
- (void)showProcessIndicatorWithAlignment:(UIViewContentMode)mode style:(UIActivityIndicatorViewStyle)style;
- (void)hideProcessIndicator;

- (BOOL)isProcessIndicatorPresented;

@end

的UIView + Additions.m

#import "UIView+Additions.h"

@implementation UIView (UIView_Additions)

- (void)showProcessIndicatorWithStyle:(UIActivityIndicatorViewStyle)style
{
    [self showProcessIndicatorWithAlignment:UIViewContentModeCenter style:style];
}

- (void)showProcessIndicator
{
    [self showProcessIndicatorWithAlignment:UIViewContentModeCenter style:UIActivityIndicatorViewStyleGray];
}

- (void)showProcessIndicatorWithAlignment:(UIViewContentMode)mode style:(UIActivityIndicatorViewStyle)style
{
    UIActivityIndicatorView *indicator = (UIActivityIndicatorView*)[[UIViewsIndicatorsPull instance] indicatorForViewObject:self style:style];
    [self positionIndicator:indicator andAlignment:mode];

    [indicator startAnimating];
    [self.superview addSubview:indicator];

    self.alpha = 0;
}

- (void)showProcessIndicatorWithAlignment:(UIViewContentMode)mode
{
    [self showProcessIndicatorWithAlignment:mode style:UIActivityIndicatorViewStyleGray];
}

- (void)positionIndicator:(UIActivityIndicatorView*)indicator andAlignment:(UIViewContentMode)mode
{
    CGRect frame = indicator.frame;

    switch (mode) {
        case UIViewContentModeRight:
            frame.origin.x = self.frame.origin.x + self.frame.size.width - frame.size.width;
            frame.origin.y = self.frame.origin.y + self.frame.size.height / 2 - frame.size.height / 2;
            indicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
            break;

        case UIViewContentModeLeft:
            frame.origin.x = self.frame.origin.x;
            frame.origin.y = self.frame.origin.y + self.frame.size.height / 2 - frame.size.height / 2;
            indicator.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
            break;

        case UIViewContentModeTop:
            frame.origin.x = self.frame.origin.x + self.frame.size.width / 2 - frame.size.width / 2;
            frame.origin.y = self.frame.origin.y;
            indicator.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
            break;

        case UIViewContentModeBottom:
            frame.origin.x = self.frame.origin.x + self.frame.size.width / 2 - frame.size.width / 2;
            frame.origin.y = self.frame.origin.y + self.frame.size.height - frame.size.height;
            indicator.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
            break;

        case UIViewContentModeTopLeft:
            frame.origin.x = self.frame.origin.x;
            frame.origin.y = self.frame.origin.y;
            indicator.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin;
            break;

        case UIViewContentModeTopRight:
            frame.origin.x = self.frame.origin.x + self.frame.size.width - frame.size.width;
            frame.origin.y = self.frame.origin.y;
            indicator.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin;
            break;

        case UIViewContentModeBottomLeft:
            frame.origin.x = self.frame.origin.x;
            frame.origin.y = self.frame.origin.y + self.frame.size.height - frame.size.height;
            indicator.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
            break;

        case UIViewContentModeBottomRight:
            frame.origin.x = self.frame.origin.x + self.frame.size.width - frame.size.width;
            frame.origin.y = self.frame.origin.y + self.frame.size.height - frame.size.height;
            indicator.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
            break;

        case UIViewContentModeCenter:
            frame.origin.x = self.frame.origin.x + self.frame.size.width / 2 - frame.size.width / 2;
            frame.origin.y = self.frame.origin.y + self.frame.size.height / 2 - frame.size.height / 2;
            indicator.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
            break;

        default:
            frame.origin.x = self.frame.origin.x + self.frame.size.width / 2 - frame.size.width / 2;
            frame.origin.y = self.frame.origin.y + self.frame.size.height / 2 - frame.size.height / 2;
            indicator.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
            break;
    }

    indicator.frame = frame;
}

- (void)hideProcessIndicator
{
    UIActivityIndicatorView *indicator = [[UIViewsIndicatorsPull instance] indicatorForViewObject:self];

    [indicator stopAnimating];
    [indicator removeFromSuperview];

    self.alpha = 1.0;
}

- (BOOL)isProcessIndicatorPresented
{
    return self.alpha == 0;
}



@end

将此文件添加到项目中,然后调用cell:

[cell.contentView showProcessIndicator];
[cell.contentView showProcessIndicatorWithAlignment:UIViewContentModeCenter];
[cell.contentView showProcessIndicatorWithAlignment:UIViewContentModeCenter style:UIActivityIndicatorViewStyleGray];

[cell.contentView hideProcessIndicator];

答案 1 :(得分:0)

对表格视图进行子类化很好。这是一个加载指示器......

-(void)addLoadingOverlay
{
    self.overlayView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.overlayView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    self.activityIndicator.center = self.overlayView.center;
    [self.overlayView addSubview:self.activityIndicator];
    [self.activityIndicator startAnimating];
    [self.navController.view addSubview:self.overlayView];
}

为uiview和活动指标制作一个出口。通过做这样的事情来移除它。

[self.activityIndicator stopAnimating];
[self.overlayView removeFromSuperview];
[self.tableView reloadData];
相关问题