Как удалить повторяющиеся элементы в iCarousel

https://github.com/nicklockwood/iCarousel/issues/278

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


Во время отладки кода я обнаружил, что функция viewForItemAtIndex вызывается 2 раза после того, как я вызвал функцию reloadData.

- (UIView *) carousel: (iCarousel *) carousel viewForItemAtIndex: (NSUInteger) index reusingView: (UIView *) view



Итак, в iCarousel 4 изображения.

Как запретить звонить 2 раза?

Пожалуйста, помогите мне решить эту проблему как можно скорее.


- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
    UIImageView *puzzlePhoto = nil;
    UIImageView *puzzleBG = nil;
    UILabel *label = nil;

    if (view == nil)
    {
        view = [[UIImageView alloc] init];
        view.frame = CGRectMake(0, 0, 128, 112);
        view.backgroundColor = [UIColor clearColor];
        view.layer.doubleSided = NO;
        puzzlePhoto = [[UIImageView alloc] initWithFrame:CGRectMake(46, 48, 40, 40)];

        //! get friend's photo
        FForesight *foresightCurrent = (carousel == self.icGameOnwhoAREus) ? [controller.gameManager.m_arrayStartedForesights objectAtIndex:index] : [controller.gameManager.m_arrayEndedForesights objectAtIndex:index];
        UIImage *imgPuzzle = [foresightCurrent getPuzzleImage];

        if (imgPuzzle)
            puzzlePhoto.image = imgPuzzle;
        else
            puzzlePhoto.image = [UIImage imageNamed:@"puzzle background_small.png"];

        puzzleBG = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 128, 112)];
        if (((foresightCurrent.m_intStage & FForesightStage_First) && !foresightCurrent.m_FCreatedByFriend) ||
            ((foresightCurrent.m_intStage & FForesightStage_Second) && foresightCurrent.m_FCreatedByFriend))
            puzzleBG.image = [UIImage imageNamed:@"multi_game_one_item_bg_me.png"];
        else
            puzzleBG.image = [UIImage imageNamed:@"multi_game_one_item_bg.png"];

        //! get friend name
        FUser *userFriend = foresightCurrent.m_userFriend;
        label = [[UILabel alloc] initWithFrame:CGRectMake(32, 32, 68, 16)];
        label.text = userFriend.m_strName;
        label.textAlignment = NSTextAlignmentCenter;
        label.font = [UIFont boldSystemFontOfSize:10];
        label.backgroundColor = [UIColor clearColor];
        label.textColor = [UIColor colorWithRed:205.0f/256 green:55.0f/256 blue:2.0f/255 alpha:1];

        [view addSubview:puzzlePhoto];
        [view addSubview:puzzleBG];
        [view addSubview:label];
    }

    return view;
}

person William Han    schedule 21.11.2012    source источник
comment
Я использовал бета-версию iCarousel 1.6.3. Итак, я только что обновился до 1.7.2 (последняя версия). Хотя фоновые изображения удалены, он не может гибко прокручиваться. Другими словами, у него нет инерции.   -  person William Han    schedule 21.11.2012
comment
Было бы полезно, если бы вы могли вставить код, который вы вводите, в свой - (UIView *) carousel: (iCarousel *) carousel viewForItemAtIndex: (NSUInteger) index reusingView: (UIView *) метод просмотра.   -  person Nick Lockwood    schedule 22.11.2012
comment
Хотя я поместил ваш пример кода (в iCarousel-master.zip, iCarousel 1.7.2) в свой проект, он тоже не прокручивается гибко   -  person William Han    schedule 22.11.2012


Ответы (2)


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

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
    UIImageView *puzzlePhoto = nil;
    UIImageView *puzzleBG = nil;
    UILabel *label = nil;

    const NSInteger puzzlePhotoTag = 1;
    const NSInteger puzzleBGTag = 2;
    const NSInteger labelTag = 3;

    if (view == nil)
    {
        //*************************************************
        //do setup that is the same for every item view here
        //*************************************************

        view = [[UIImageView alloc] init];
        view.frame = CGRectMake(0, 0, 128, 112);
        view.backgroundColor = [UIColor clearColor];
        view.layer.doubleSided = NO;

        puzzlePhoto = [[UIImageView alloc] initWithFrame:CGRectMake(46, 48, 40, 40)];
        puzzlePhoto.tag = puzzlePhotoTag;
        [view addSubview:puzzlePhoto];

        puzzleBG = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 128, 112)];
        puzzleBG.tag = puzzleBGTag;
        [view addSubview:puzzleBG];

        label = [[UILabel alloc] initWithFrame:CGRectMake(32, 32, 68, 16)];
        label.textAlignment = NSTextAlignmentCenter;
        label.font = [UIFont boldSystemFontOfSize:10];
        label.backgroundColor = [UIColor clearColor];
        label.textColor = [UIColor colorWithRed:205.0f/256 green:55.0f/256 blue:2.0f/255 alpha:1];
        label.tag = labelTag;
        [view addSubview:label];
    }
    else
    {
        //get references to subviews
        puzzlePhoto = (UIImageView *)[view viewWithTag:puzzlePhotoTag];
        puzzleBG = (UIImageView *)[view viewWithTag:puzzleBGTag];
        label = (UILabel *)[view viewWithTag:labelTag];
    }

    //*************************************************
    //do setup that is different depending on index here
    //*************************************************

    //! get friend's photo
    FForesight *foresightCurrent = (carousel == self.icGameOnwhoAREus) ? [controller.gameManager.m_arrayStartedForesights objectAtIndex:index] : [controller.gameManager.m_arrayEndedForesights objectAtIndex:index];
    UIImage *imgPuzzle = [foresightCurrent getPuzzleImage];

    if (imgPuzzle)
        puzzlePhoto.image = imgPuzzle;
    else
        puzzlePhoto.image = [UIImage imageNamed:@"puzzle background_small.png"];

    if (((foresightCurrent.m_intStage & FForesightStage_First) && !foresightCurrent.m_FCreatedByFriend) || ((foresightCurrent.m_intStage & FForesightStage_Second) && foresightCurrent.m_FCreatedByFriend))
        puzzleBG.image = [UIImage imageNamed:@"multi_game_one_item_bg_me.png"];
    else
        puzzleBG.image = [UIImage imageNamed:@"multi_game_one_item_bg.png"];

    //! get friend name
    FUser *userFriend = foresightCurrent.m_userFriend;
    label.text = userFriend.m_strName;

    return view;
}

Что касается проблемы с инерцией прокрутки, если вы все еще видите это после применения этого исправления, отправьте отдельный отчет об ошибке на странице github.

person Nick Lockwood    schedule 22.11.2012
comment
Спасибо за ваш ответ, но это то же самое, хотя я следую за вами. - person William Han; 22.11.2012
comment
Если ваша карусель не продолжает прокручиваться, когда вы ее отпускаете, это может быть связано с изменениями таймера в 1.7.2. Попробуйте использовать 1.7.1 со страницы тегов на github и посмотрите, будет ли это иметь значение. - person Nick Lockwood; 23.11.2012
comment
эй @NickLockwood, я пытался этим способом, но получаю проблему несоответствия, не получая точных представлений. Я использую iCarouselTypeRotary с iCarouselOptionWrap == true. - person bLacK hoLE; 03.02.2016

Я решил эту проблему, выполнив reloadData на mainThread

[carousel performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
person Shamsiddin    schedule 02.05.2013