2014-02-13 8 views
1

Я работаю в проекте (iOS7 & ARC), в котором я хочу, чтобы отобразить N число изображений в спиральном view.These Изображения уже хранятся в директории песочнице. Моя App имеет только альбомной ориентации я столкнулся с проблемой, что ScrollView не является гладким, он застрял после 2-3 раза прокрутитьвид прокрутки не гладкая

Это, как настроить ScrollView

[self.containerScroll setAutoresizesSubviews:NO]; 
self.containerScroll.pagingEnabled = YES; 
self.containerScroll.showsHorizontalScrollIndicator = NO; 
self.containerScroll.showsVerticalScrollIndicator = NO; 
self.containerScroll.scrollsToTop = NO; 
self.containerScroll.maximumZoomScale = 5.0; 
self.containerScroll.minimumZoomScale = 1.0; 
self.containerScroll.delegate = self; 

Я поддерживая только три изображения в scrollView за раз.

я загружаю изображения в ScrollView ниже в методе

-(void) loadScrollViewWithPage:(int) page{ 

if (page >= self.numberOfSlides) 
    return; 

float image_width; 
float image_height; 

if(self.isFromListView){ 

    if(IS_IPHONE5){ 
     image_width = 568.0f; 
     image_height = 320.0f; 
    } else{ 
     // iPhone retina-3.5 inch 
     image_width = 480.0f; 
     image_height = 320.0f; 
    } 

} 
else{ 
    image_width = IMAGE_WIDTH; 
    image_height = IMAGE_HEIGHT; 
} 

CGFloat xPos = page * image_width; 
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(xPos, 0.0f, image_width, image_height)]; 
imgView.tag = page; 
NSString *imgPath = [self.storageDirPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d%@", page, Image_Extension_JPG]]; 

NSFileManager *fileManager = [NSFileManager defaultManager]; 
__block UIImage *img = nil; 
if(![fileManager fileExistsAtPath:imgPath]){ 
    [imgView setContentMode:UIViewContentModeCenter]; 
    img = [UIImage imageNamed:@"icon-loader.png"]; 
    [imgView setImage:img]; 
} 
else{ 
    [imgView setContentMode:UIViewContentModeScaleAspectFit]; 
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 

       img = [[UIImage alloc] initWithCGImage:[[UIImage imageWithData:[NSData dataWithContentsOfFile:imgPath]] CGImage] scale:1.0 orientation:UIImageOrientationUp]; 

         dispatch_async(dispatch_get_main_queue(), ^{ 
         [imgView setImage:img]; 
       }); 

      }); 
} 

[self.containerScroll addSubview:imgView]; 
img = nil; 
fileManager = nil; 
imgView = nil; 

}

и это, как мои ScrollView методы делегата идет ...

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
{ 
    self.containerScroll.scrollEnabled = YES; 

    float page = self.containerScroll.contentOffset.x/self.view.frame.size.width; 
    showingSlide = (UInt16) roundf(page); 

    if(scrollView == self.containerScroll){ 

     // switch the indicator when more than 50% of the previous/next page is visible 
     CGFloat pageWidth = CGRectGetWidth(self.containerScroll.frame); 
     NSUInteger pageNo = floor((self.containerScroll.contentOffset.x - pageWidth/2)/pageWidth) + 1; 

     // load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling) 
     [self loadScrollViewWithPage:pageNo - 1]; 
     [self loadScrollViewWithPage:pageNo]; 
     [self loadScrollViewWithPage:pageNo + 1]; 

     // a possible optimization would be to unload the views+controllers which are no longer visible 

     if(scrollView == self.containerScroll) 
     { 
      [self.previewTableView reloadData]; 
      [self.previewTableView setContentOffset:CGPointMake(0, (page*220)+64) animated:NO]; 
      [self.previewTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:page inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; 

      [self updateSlideNumber]; 
      [self flashSlideNumber]; 
     } 

     //unload unnecessary imageviews from scroll view 
     for (UIView* view in self.containerScroll.subviews) { 
      if ([view isKindOfClass:[UIImageView class]] && view.tag != page && view.tag != page-1 && view.tag != page+1) { 
       [view removeFromSuperview]; 
      } 
     } 

    } 
} 

Теперь проблема гладкости scrollView. Когда я начинаю прокручивать, он прокручивается нормально, но после 2 или 3 (или после случайного числа) страниц прокручивается, он застревает, и после попытки в 2-3 раза он снова перемещается, и мне приходится сильно прокручивать прокрутку. Заранее спасибо.

ответ

0

Я думаю, что это проблема памяти. Попробуйте @autorelease пул в вашем коде.

+0

Я уже пробовал этот путь ... не повезло. – Suryakant

0

Использование scrollview не является хорошим подходом для показа изображений, я порекомендую вам либо использовать представление tableview, либо collevtionview для него.

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

+0

вы и @HookShot правы. Должны использовать TableView или коллекцию, но на этом этапе проекта я не могу этого сделать ... должен идти с ScrollView. – Suryakant

0

Как самый эффективный способ стать лучше, прокрутите очень медленно (по одному за раз), пока вы контролируете использование памяти в своем приложении. Вы сможете посмотреть, как это происходит, поскольку каждое новое изображение добавляется в представление, особенно если вы не сделали никакой оптимизации на изображениях.

Другое дело в том, что, хотя ваш код действительно похож на отмену изображений, вам все равно нужно помнить, что он все равно должен попытаться перезагрузить изображения при прокрутке. Вы создаете свои изображения в основном потоке, чтобы никогда не получить гладкость UITableView. Хотя я понимаю, что вы создаете свои изображения на асинхронных потоках, действие добавления и прокрутки их по-прежнему заботится по mainthread.

Я бы предложил UITableView для решения вашей проблемы или UICollectionView. Если вы настроитесь на использование прокрутки, я бы предложил использовать дробилку какого-то типа, чтобы размер изображения был как можно меньше, при этом сохраняя качество приличным.

Если вам нужна помощь в реализации TableView, вы должны найти много информации вокруг SO. Вероятно, хороший вариант, если вы все еще хотите, чтобы он выглядел как вид прокрутки, - это просто сделать все разделители, заголовки и т. Д. Равными нулю, а затем просто использовать ленивую загрузку изображений.

+0

после того, как изображение добавлено в ImageView. Я просто устанавливаю его на нуль. В чем проблема? – Suryakant

+0

Я думаю, что проблема заключается в фактическом времени чтения изображений, поскольку они загружаются в свиток. Можете ли вы проверить инструменты, когда они загружены, чтобы увидеть время, необходимое для выполнения нагрузки? Я бы предложил использовать дробилку в качестве вашего первого шага - это может решить все ваши проблемы, даже не изменив код слишком сильно. Возможно ли, что вы уже объявили все UIImage (ы) и просто выделили их в UIImageView при прокрутке, чтобы изображения уже были в памяти, в контейнерах, готовых для загрузки в UIImageView? – crashlog

+0

http://imageoptim.com/ - Это ссылка на хорошего пользователя imagecrusher для пользователя Xcode/Webstuff =] – crashlog

0

Вы делаете две ошибки. Сначала: никогда не используйте imageNamed для неграфического содержимого (например, используйте imageNamed для фона кнопки).И второе: вы пытаетесь загрузить большие изображения в режиме реального времени. Таким образом, вы просматриваете представление. Если вы загрузите все изображения, прежде чем вы покажете, что прокрутка просматривает конец запаса аминации. Но вы можете получить предупреждения о памяти. Поэтому вам нужно его оптимизировать. Постскриптум Извините за мой английский

+0

Вы написали проклятый хороший английский. Не нужно сожалеть Сначала: imageNamed метод появляется на картинке, когда реально Изображение нет, так что давайте не будем обсуждать этот случай. мой ScrollView отстает, когда imageNamed не получает вызов даже один раз. так что это не проблема. и Second: я не могу позволить загружать все изображения в память, потому что у меня может быть любое количество изображений. – Suryakant

Смежные вопросы