在SDWebImage中显示活动指示器

时间:2012-06-29 12:56:40

标签: objective-c uiactivityindicatorview sdwebimage

我正在使用SDWebView图像,我希望在从远程获取图像时将活动指示器显示为占位符。

我在这里尝试了Malek的答案How to show an activity indicator in SDWebImage,但似乎

UIImage *cachedImage = [manager imageWithURL:url];

已弃用。

是否有人使用此库可以告诉我如何在加载图像时插入活动指示器?

修改

根据Michael Frederick的指示,我最终得到了这段代码,一切正常。

UIActivityIndicatorView *activityIndicator = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite] autorelease];
activityIndicator.hidesWhenStopped = YES;
activityIndicator.hidden = NO;
[activityIndicator startAnimating];
activityIndicator.center = CGPointMake(self.tipImage.frame.size.width /2, self.tipImage.frame.size.height/2);
[imageView setImageWithURL:[NSURL URLWithString:imageString]
          placeholderImage:nil options:SDWebImageProgressiveDownload
                   success:^(UIImage *image) { [activityIndicator stopAnimating];[activityIndicator removeFromSuperview]; }
                   failure:^(NSError *error) {  [activityIndicator stopAnimating];[activityIndicator removeFromSuperview]; }];

[imageView addSubview:activityIndicator];

18 个答案:

答案 0 :(得分:47)

This fork支持此功能。看看the diff

但是,一般来说,你可以在不使用该分支的情况下轻松地完成它:

__block UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:activityStyle];
activityIndicator.center = imageView.center;
activityIndicator.hidesWhenStopped = YES;
[imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
               placeholderImage:[UIImage imageNamed:@"placeholder.png"]
                        success:^(UIImage *image) { [activityIndicator removeFromSuperview]; }
                        failure:^(NSError *error) { [activityIndicator removeFromSuperview]; }];

[imageView addSubview:activityIndicator];
[activityIndicator startAnimating];

答案 1 :(得分:22)

您就是这样做的:



[imageView setIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[imageView setShowActivityIndicatorView:true];
[imageView sd_setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:@"defaultl_image"]];




答案 2 :(得分:17)

这是我的解决方案。在该文件中:UIImageView + WebCache.m

找到那个方法并改变:

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder
{
    UIActivityIndicatorView *activity = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyleGray)];
    [activity startAnimating];
    [activity setFrame:CGRectMake(self.frame.origin.x - 20, self.frame.origin.y - 10, self.frame.size.width, self.frame.size.height)];
    [self addSubview:activity];

    //[self setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];

    [self setImageWithURL:url
         placeholderImage:placeholder
                  options:0
                completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
     {
             [activity removeFromSuperview];
     }];
}

答案 3 :(得分:15)

最后解决方案

您可以下载UIActivityIndicator-for-SDWebImage,这是向您的SDWebImage视图添加UIActivityView的最简单方法。使用CocoaPods,只需将此行添加到podfile:

pod 'UIActivityIndicator-for-SDWebImage'

您可以根据自己的喜好使用其中一行:

- (void)setImageWithURL:(NSURL *)url usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;

使用示例

只需导入

#import <UIActivityIndicator-for-SDWebImage/UIImageView+UIActivityIndicatorForSDWebImage.h>

并使用此代码

[imageView setImageWithURL:[NSURL URLWithString:@"https://media.licdn.com/mpr/mpr/wc_200_200/p/1/005/07f/0a3/30cb8dd.jpg"] placeholderImage:[UIImage imageNamed:@"myImage.jpg"] usingActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

答案 4 :(得分:5)

以上代码略有错误。行'activityIndi​​cator.center = imageView.center'没有为您提供正确的坐标以使进度视图居中。对我来说,它显示了细胞下方的指标。

注意 - 我使用的是最新版本的SDWebImage代码,因此方法略有不同。我也在使用UIButton作为imageView

试试这个:

NSURL *url = [NSURL URLWithString:@"www.someimageurl.com"];
__block UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.frame = cell.imageView.bounds;
[cell.imageView addSubview:activityIndicator];
[activityIndicator startAnimating];
[cell.imageView setImageWithURL:url forState:UIControlStateNormal completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
    [activityIndicator removeFromSuperview];
}];

答案 5 :(得分:5)

我相信最新版本的sdwebimage这是一种更好的方法。

[self.customImageView setImageWithURL:imageURL
                             placeholderImage:nil
                                      options:nil
                                     progress:^(NSUInteger receivedSize, long long expectedSize) { [self.activityIndicator startAnimating]; }
                                    completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) { [self.activityIndicator stopAnimating]; }];

注意:如果您没有设置属性,那么self.activityindicator将无效。

我会用Michael Frederick的例子来创建activityindicator。

答案 6 :(得分:4)

SDWebImage具有内置的活动指示器,可以完美地运行。试试这个:

斯威夫特3:

imgView.setShowActivityIndicator(true)
imgView.setIndicatorStyle(.gray)
imgView.sd_setImage(with: URL(string: urlString), placeholderImage: UIImage(named: "placeholder"))

答案 7 :(得分:3)

与SWIFT 4中的上述代码相同:

let activityIndicator = UIActivityIndicatorView.init(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
    activityIndicator.center = addImage.center
    activityIndicator.hidesWhenStopped = true

    addImage.sd_setImage(with: URL(string: feed.image), completed: { (image: UIImage?, error: Error?, cacheType: SDImageCacheType, imageURL: URL?) in
        activityIndicator.removeFromSuperview()
    })

    addImage.addSubview(activityIndicator)
    activityIndicator.startAnimating()

答案 8 :(得分:2)

[cell.dreamImageView setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",dream.thumbnail]] placeholderImage:[UIImage imageNamed:@"dream_bg_2.png"] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {

    CGFloat domandeFloat = [[NSNumber numberWithInt: receivedSize] floatValue];
    CGFloat corretteFloat = [[NSNumber numberWithInt: expectedSize] floatValue];


    float currentProgress = domandeFloat/corretteFloat;

     NSLog(@"progress %f",currentProgress);
    cell.progressView.progress = currentProgress;

    //[self.dreamsTableView reloadData];


} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {

    cell.progressView.hidden = YES;
}];

答案 9 :(得分:2)

为Swift 2.0更新解决方案,使用SDWebImage加载图片网址

imageView.setShowActivityIndicatorView(true)

imageView.setIndicatorStyle(.White)

答案 10 :(得分:1)

根据CanÜrek的回答,您可能想要创建一个类别,以便更容易在多个应用程序中使用,而无需修改SDWebImage框架

标题文件:

#import <UIKit/UIKit.h>

#import <SDWebImage/UIImageView+WebCache.h>

@interface UIImageView (WebCacheWithActivityIndicator)

- (void)setImageShowingActivityIndicatorWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock;

@end

实施档案:

#import "UIImageView+WebCacheWithActivityIndicator.h"

@implementation UIImageView (WebCacheWithActivityIndicator)

- (void)setImageShowingActivityIndicatorWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock
{
    UIActivityIndicatorView* activityIndication = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

    [activityIndication setFrame:CGRectMake((self.frame.size.width - activityIndication.frame.size.width) / 2 , (self.frame.size.height - activityIndication.frame.size.height) / 2 , activityIndication.frame.size.width , activityIndication.frame.size.width)];
    [self addSubview:activityIndication];

    [activityIndication startAnimating];

    [self setImageWithURL:url completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {

        if(completedBlock)
        {
            completedBlock(image,error,cacheType);
        }

        [activityIndication stopAnimating];
        [activityIndication removeFromSuperview];
    }];
}
@end

希望它可以帮助你们帮助你们

干杯

答案 11 :(得分:1)

对于Swift 5.0和SDWebImage 5.0:

替换

#COMBO MAKER
def combo_input_maker():#<--Populate combo_maker
    # use global cursor instead of local one
    cursor.execute("SELECT maker_name FROM makers")
    result=[rec[0] for rec in cursor]
    return result
#COMBO MAKER

#COMBO TYPE
def combo_input_type(event=None):#<--Populate combo_type
    some_name = combo_maker.get()#<--Query with value select from combo_maker
    # use global cursor
    cursor.execute("SELECT t1.type FROM maker_types t1 INNER JOIN makers t2 ON t1.maker_id = t2.id WHERE maker_name = %s", [some_name])
    result = [rec[0] for rec in cursor]
    # populate combo_type
    combo_type['value'] = result
    combo_type.current(0)
    return result
#COMBO TYPE

# connect DB once
conn = connect_db()
cursor = conn.cursor()

combo_maker = ttk.Combobox(Product,state="readonly")
combo_maker['value'] = combo_input_maker() #[item for result in combo_input_maker() for item in result if item]
combo_maker.bind('<<ComboboxSelected>>', combo_input_type) # use function reference here
combo_maker.place(x=5, y=5, height = 25, width = 180)

combo_type = ttk.Combobox(Product,state="readonly")
combo_type.place(x=200, y=5, height = 25, width = 180)

通过

imageView.sd_setShowActivityIndicatorView(true)
imageView.sd_setIndicatorStyle(.gray)

答案 12 :(得分:1)

SdWebImage 5.0

YOUR_IMAGEVIEW.sd_imageIndicator = SDWebImageActivityIndicator.gray

答案 13 :(得分:0)

SDWebImage 5.0支持使用SDWebImageActivityIndi​​cator类显示活动指示器。

let imageView = UIImageView()
imageView.sd_imageIndicator = SDWebImageActivityIndicator.gray

答案 14 :(得分:0)

对我有用的最佳解决方案如下。在下载图像时显示进度指示器是美观且令人鼓舞的。我使用UICircularSlider作为舍入进度视图。你也可以尝试一下。

# Sample data
df = data.frame(col1=c(1,0,3,4,5,6,107,8,9), col2=c(9,8,7,6,5,4,3,2,1))

#   col1 col2
# 1    1    9
# 2    0    8
# 3    3    7
# 4    4    6
# 5    5    5
# 6    6    4
# 7  107    3
# 8    8    2
# 9    9    1

# Function to evaluate condition ==0 or 3 digits    
cond <- function(x) { any(x==0 | x>=100 & x<=999); }

# Add column telling whether to swap by running the cond function over groups
# of three. Expand the groups again by repeating each value 3 times to match
# the rows.
df$swap = rep(lapply(split(df$col1, ceiling(seq_along(df$col1)/3)), FUN=cond), each=3)

# Swap the indicated rows
df[df$swap==TRUE,][c('col1', 'col2')] = df[df$swap==TRUE,][c('col2', 'col1')]

# Remove the swap column
df <- within(df, rm(swap))

#   col1 col2
# 1    9    1
# 2    8    0
# 3    7    3
# 4    4    6
# 5    5    5
# 6    6    4
# 7    3  107
# 8    2    8
# 9    1    9

此处 [_imgPost sd_setImageWithURL:urlPost placeholderImage:zeroImage options:SDWebImageContinueInBackground progress:^(NSInteger receivedSize, NSInteger expectedSize) { CGFloat domandeFloat = [[NSNumber numberWithInteger: receivedSize] floatValue]; CGFloat corretteFloat = [[NSNumber numberWithInteger: expectedSize] floatValue]; float currentProgress = (domandeFloat/corretteFloat)*100; NSLog(@"progress %.f%%",currentProgress); DBG(@"%li, %li", receivedSize, expectedSize); [_progress setValue:currentProgress]; } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { [_progress setHidden:YES]; }]; _progress

的实例

答案 15 :(得分:0)

当用户反复上下滚动列表时,我的列表相当滞后。我发现当重复调用cellForItemAtIndexPath时,activityindicator已被无限添加。

要解决此问题,请在您的activityindicator中添加一个标记:

activityIndicator.tag = 9999;

在创建UIActivityIndi​​cator之前,添加这些行以删除之前的activityindicator,然后再添加新的:

UIView* toDeleteLoader = [cell viewWithTag:9999];
if(toDeleteLoader != nil){
    [toDeleteLoader removeFromSuperview];
}

注意:标记内容可以是您在单元格中使用的任何数字。

答案 16 :(得分:0)

使用更新的library(iOS 8上已解决的崩溃),我们有以下方法 -

- (void)sd_setImageWithURL:(NSURL *)url 
{
    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
}

正如我们可以看到添加进度块和已完成块的选项,我们只需在进度块中添加活动指示器并在完成块中删除。

在此处添加活动指标的自定义方法 -

- (void)sd_setImageWithURL:(NSURL *)url {

    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
        UIActivityIndicatorView *activity = nil;
        activity = (UIActivityIndicatorView *)[self viewWithTag:100000];
        if (!activity) {
            activity = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
            [activity setTag:100000];
            [activity setHidesWhenStopped:YES];
            [activity setCenter:CGPointMake(self.frame.size.width/2.0f,self.frame.size.height/2.0f)];
            [self addSubview:activity];
        }
        else {
            [activity setCenter:CGPointMake(self.frame.size.width/2.0f,self.frame.size.height/2.0f)];
        }
        [activity startAnimating];

    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
        UIActivityIndicatorView *activity = (UIActivityIndicatorView *)[self viewWithTag:100000];
        if ([activity isKindOfClass:[UIActivityIndicatorView class]]) {
            [activity stopAnimating];
        }
    }];
}

这将在正在下载图像时将UIActivityIndi​​catorView添加到UIImageView的中心,并在完成时删除。

答案 17 :(得分:0)

另一种解决方案是使用动画图像作为占位符图像:

[UIImage animatedImageNamed:@"animated_placeholder" duration:1]