Изображение UIButton асинхронно

#iphone #objective-c #ipad

#iPhone #objective-c #iPad

Вопрос:

У меня есть куча UIButton в UIScrollView, и каждая UIButton принимает изображение из URL. Каков самый простой способ, чтобы изображение загружалось асинхронно?

Например, обычным способом является:

 [button setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];
  

но это блокирует пользовательский интерфейс, я не хочу, чтобы это

Комментарии:

1. Я думаю, что вам нужно заменить кучу кнопок на asynchImageview, используя asynchImageview, вы можете получать событие касания при каждом просмотре изображения, не затрагивая другое asynchView. и синхронизация решают проблемы с блоками.

Ответ №1:

Вы можете попробовать это

      [self performSelectorInBackground:@selector(loadImag) withObject:nil];
  

В функции LoadImage загрузите изображение с URL, а затем назначьте его кнопке.
Я не уверен, что это сработает для you…As Я новичок в разработке objective C

Комментарии:

1. нет.. вы не можете установить какие-либо параметры пользовательского интерфейса не из основного потока, кроме того, в этом случае LoadImage должен принимать кнопку в качестве параметра

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

3. @JoshCaswell тогда нам нужно было бы передать в UIButton изображение, которое мы хотим установить, вместе с URL-адресом в методе LoadImage.. как вы это делаете? Если вы можете предоставить код для этого, я бы принял ответ

4. @aher: Передайте URL в качестве withObject аргумента performSelector... вызова. Затем в loadImage методе верните данные изображения в основной поток с performSelectorOnMainThread:withObject:

5. @JohnCaswell Я знаю метод performSelectorOnMainThread, но нам нужна кнопка, чтобы установить изображение здесь.. как мне получить это в методе LoadImage? По сути, вам пришлось бы инкапсулировать это в словарь и передать его withObject, верно?

Ответ №2:

Попробуйте с помощью NSInvocationOperation выполнить синхронный запрос для каждой кнопки изображения… Передайте кнопку в качестве параметра, я имею в виду что-то вроде этого…

Инициализирует очередь операций (возможно, при инициализации):

 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  

запустите вызов операции для каждой кнопки…

 NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self 
                                                                        selector:@selector(getImageFromURL:) 
                                                                          object:[NSDictionary dictionaryWithObjectsAndKeys:@"http://getMyImage.com/resource.jpg", @"url", button, @"button", nil]];

[queue addOperation:operation];
[operation release];
  

это может быть ваш getImageFromURL: селектор

 - (void) getImageFromURL:(NSDictionary*)dict
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSURL *url = [NSURL URLFromString:[dict objectForKey:@"url"]];
    UIButton *button = [dict objectForKey:@"button"];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:amp;error];
    UIImage *image = [[UIImage alloc] initWithData:data];

    // Finally set the button image and release image ...
    [pool drain];
}
  

Не забудьте освободить очередь при освобождении…

Надеюсь, это поможет! 🙂

Ответ №3:

Я думаю, это нормально, если вы блокируете при загрузке одного изображения? Проблема в том, что у вас их много? Если это так, то я бы сделал вот так (потоки не нужны):

 #define DELAY 0.1 // you may set it to 0 as well

    ...
    [self performSelector:@selector(setupButton:)
               withObject:[NSNumber numberWithInt:0]
               afterDelay:DELAY];
    ...

-(void)setupButton:(NSNumber*)count
{
    UIButton *button = [self buttonFromMyScrollViewWithCount:count.intValue];
    [button setImage:...];
    if (count.intValue < self.numberOfButtonsInMyScrollView)
        [self performSelector:@selector(setupButton:)
                   withObject:[NSNumber numberWithInt:count.intValue   1]
                   afterDelay:DELAY];
}