Показывать индикатор активности в SDWebImage

Я использую изображение SDWebView и хочу показать индикатор активности в качестве заполнителя при извлечении изображения с удаленного компьютера.

Я попробовал ответить Малека здесь Как показать индикатор активности в SDWebImage, но кажется, что

UIImage *cachedImage = [manager imageWithURL:url];

устарела.

Кто-нибудь, использующий эту библиотеку, может сказать мне, как я могу вставить индикатор активности при загрузке изображения?

ИЗМЕНИТЬ

Следуя указаниям Майкла Фредерика, я получил этот код, и все работает нормально.

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];

person Phillip    schedule 29.06.2012    source источник
comment
Получилось ли у вас работать с изображением-заполнителем?   -  person Shri    schedule 08.11.2012
comment
Я решил использовать только счетчик вместо изображения, и да, это сработало!   -  person Phillip    schedule 10.11.2012
comment
@Pheel, пожалуйста, не добавляйте ответ в вопрос, добавьте отдельный ответ (вы можете отвечать на свои вопросы). Формат SO - это вопрос + ответ (ы).   -  person Cristik    schedule 10.11.2016


Ответы (18)


Эта вилка поддерживает эту функцию. Взгляните на различие.

Но в целом вы можете сделать это довольно легко и без этой вилки:

__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];
person Michael Frederick    schedule 01.07.2012
comment
Спасибо, я уже проверил их, но что-то неясно: мне использовать его С или БЕЗ заполнителя? Потому что это не сработало! Куда должен идти этот фрагмент? - person Phillip; 01.07.2012
comment
Это может работать с заполнителем, если вы добавите activityIndicator после того, как выполните setImageWithURL. Фрагмент должен находиться там, где вы обычно устанавливаете изображение imageView. - person Michael Frederick; 01.07.2012
comment
К сожалению, это не работает. Он загружает заполнитель и т. Д., Но не ActivityIndicator - person Phillip; 01.07.2012
comment
Для комментариев выше, в которых упоминается, что это решение не работает: вам нужно добавить эту строку после вашего addSubview: [activityIndicator startAnimating]; - person Allan Jiang; 12.10.2014
comment
Когда нам следует прекратить анимацию? Он работает, но не останавливается после загрузки изображения. - person Reaper; 19.12.2014

Вот как вы это делаете:

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

person Zaldy    schedule 22.07.2015
comment
Я подтверждаю, что это лучшее на данный момент решение, поскольку в основной репозиторий наконец-то добавлен индикатор активности в этом коммите: github.com/rs/SDWebImage/commit/ - person AmineG; 08.10.2015
comment
@SourabhSharma Это не лучший вариант, потому что вам нужно написать 3 строки кода для той же функциональности. Что тоже не очень хорошая практика. - person Deepak Chaudhary; 05.05.2017
comment
@DeepakChaudhary Хорошо, тогда как лучше всего показать индикатор? - person Sourabh Sharma; 06.05.2017
comment
@SourabhSharma Создайте расширение imageView или переопределите метод инициализации imageview, затем используйте эти две строки. Таким образом, вы должны написать их только один раз для всего приложения. :) - person Deepak Chaudhary; 06.05.2017

Это мое решение. В этом файле: 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];
     }];
}
person Can Ürek    schedule 16.07.2013
comment
Сработало отлично. Вы также можете добавить его с новым именем, сохранив исходное. - person Pelanes; 25.03.2014

Последнее решение

Вы можете загрузить UIActivityIndicator-for-SDWebImage, который является самым простым способом добавить UIActivityView к вашему <▪SDWebImage просмотр. Используя CocoaPods, просто добавьте эту строку в свой подфайл:

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];
person E-Riddie    schedule 02.10.2014
comment
Действительно! Раньше этого решения не было. Но +1 за более новое решение! - person Phillip; 02.10.2014

SDWebImage имеет встроенный индикатор Acitvity, который отлично работает. Попробуй это:

Обновления: SWIFT 5 SDWebImage 5.x.x

        imgView.sd_imageIndicator = SDWebImageActivityIndicator.gray
        imgView.sd_setImage(with: url, placeholderImage: UIImage(named: "placeholder"))

Swift 3:

imgView.setShowActivityIndicator(true)
imgView.setIndicatorStyle(.gray)
imgView.sd_setImage(with: URL(string: urlString), placeholderImage: UIImage(named: "placeholder"))
person Ankit Kumar Gupta    schedule 24.02.2017

Для Swift 5.0 и SDWebImage 5.0:

Заменять

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

By

imageView.sd_imageIndicator = SDWebImageActivityIndicator.gray
person BSK-Team    schedule 03.05.2019

Приведенный выше код немного неверен. Строка «activityIndicator.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];
}];
person JimmyJammed    schedule 13.03.2013
comment
Я использовал тот же код, что и вы, и ActivityIndicator будет отображаться на секунду, а затем немедленно исчезнет. Я прокомментировал строку, которая гласит: «Удалите это ... Ничего из того, что я попробую, не заставит его остаться». Он просто появляется, а затем быстро исчезает. :( - person Hackmodford; 21.03.2013

Я считаю, что с последней версией 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 не будет работать.

Вместо этого я бы использовал пример Майкла Фредерика для создания индикатора активности.

person Hackmodford    schedule 27.03.2013

Тот же код, что и в 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()
person Ignacio Oroná    schedule 20.02.2018

SdWebImage 5.0

YOUR_IMAGEVIEW.sd_imageIndicator = SDWebImageActivityIndicator.gray
person Ahmadreza    schedule 30.04.2019

В Swift 2.0 обновлено решение для использования SDWebImage для загрузки URL изображения

imageView.setShowActivityIndicatorView(true)

imageView.setIndicatorStyle(.White)
person Sourabh Sharma    schedule 02.11.2015

Основываясь на ответе Джана Юрека, вы, возможно, захотите создать категорию, чтобы упростить использование в нескольких приложениях и без изменения структуры 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

Надеюсь, это поможет вам, ребята

Ваше здоровье

person Paulo Miguel Almeida    schedule 20.02.2014

Другое решение - использовать анимированное изображение в качестве изображения-заполнителя, используя:

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

person Joseph Toronto    schedule 26.04.2014

С обновленной библиотекой (устраненный сбой в 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];
        }
    }];
}

Это добавит UIActivityIndicatorView в центр UIImageView во время загрузки изображения и удалит по завершении.

person Abhishek    schedule 16.06.2015

Мой список сильно отстает, когда пользователь многократно прокручивает список вверх и вниз. Я обнаружил, что индикатор активности добавлялся бесконечно при многократном вызове cellForItemAtIndexPath.

Чтобы решить эту проблему, добавьте тег к индикатору активности:

activityIndicator.tag = 9999;

Перед созданием UIActivityIndicator добавьте эти строки, чтобы удалить предыдущий индикатор активности перед добавлением нового:

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

Примечание: содержание тега может быть любым числом, которое не будет использоваться в вашей ячейке.

person Loi Hui Lye    schedule 16.07.2015

Лучшее решение, которое сработало для меня, ниже. Показывать индикатор прогресса при загрузке изображения - это красиво и обнадеживающе. Я использовал UICircularSlider в качестве округленного представления прогресса. Вы также можете попробовать.

    [_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 - это экземпляр UICircularSlider

person Vaibhav Saran    schedule 26.03.2016

SDWebImage 5.0 поддерживает отображение индикатора активности с помощью класса SDWebImageActivityIndicator.

let imageView = UIImageView()
imageView.sd_imageIndicator = SDWebImageActivityIndicator.gray
person RGhate    schedule 25.09.2020

person    schedule
comment
Почему мой expectedSize равен 0 на некоторых изображениях? - person Gank; 21.07.2015