Minkle Garg
Minkle Garg

Reputation: 1395

smooth scrolling of imageview

I have added the images to scrollview dynamically. Following is the code:

-(void)displayimages {
    for (int i=0; i<[featuredarray count]; i++) {
        NSString *image=[[featuredarray objectAtIndex:i]objectForKey:@"img"];

        if (i==0) {
            webview=[[UIImageView alloc]initWithFrame:CGRectMake(i*290+15, 0, 270, 380)];
        }
        else {
            webview=[[UIImageView alloc]initWithFrame:CGRectMake(i*290+15, 0, 270, 380)];
        }
        webview.backgroundColor=[UIColor clearColor];
        webview.layer.borderWidth=4;
        webview.layer.cornerRadius=4;
        webview.layer.borderColor=[[UIColor whiteColor]CGColor];
        [webview setTag:i];
        webview.userInteractionEnabled=YES;
        NSURL *url = [NSURL URLWithString:image];
        [webview setImageWithURL:url placeholderImage:[UIImage 
           imageNamed:@"placeholder.png"]];
        [scroll addSubview:webview];

        UITapGestureRecognizer *tap1 =
        [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handlefirstTap:)];
        tap1.delegate=self;
        tap1.numberOfTapsRequired=1;
        [webview addGestureRecognizer:tap1];
        [tap1 release];
        [webview release];
   }

   pages.defersCurrentPageDisplay=YES;
   scroll.delegate =self;

   scroll.contentSize = CGSizeMake(290*[featuredarray count],300);
   scroll.pagingEnabled = YES;
   pages.numberOfPages = [featuredarray count]-1;
   pages.currentPage =0;
}

-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
    int gallerypage = scrollView.contentOffset.x /scrollView.frame.size.width;
    CGRect frame = scroll.frame;
    frame.origin.x = frame.size.width-15*gallerypage;
    NSLog(@"frame.origin.x..%f",frame.origin.x);
    frame.origin.y =0;
    [scroll scrollRectToVisible:frame animated:YES];
}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    int gallerypage = scrollView.contentOffset.x /scrollView.frame.size.width;
    CGRect frame = scroll.frame;
    frame.origin.x=gallerypage*290;
    frame.origin.y =0;
    [scroll scrollRectToVisible:frame animated:YES];
}

It is showing the images well when I use pagecontroller action

-(IBAction)pagecontrolaction:(id)sender {
    int page = pages.currentPage;
    CGRect frame = scroll.frame;
    frame.origin.x=page*290;
    frame.origin.y =0;
    [scroll scrollRectToVisible:frame animated:YES];
}

but when I used touch event to imageview then it is not displaying the images smoothly. It gets stuck during scrolling.

These are the preview which shows the current image with the start of second image.

Upvotes: 3

Views: 891

Answers (8)

gleb.kudr
gleb.kudr

Reputation: 1508

You should definitely resize your image in background prior to loading it into UIImageView. Also you should set UIImageView content mode to the none-resizing one. It gave me significantly scrolling improvement after other ways were already implemented (async cache and others).

Upvotes: 0

Kundan
Kundan

Reputation: 3082

It happens when you are trying to show an image of larger size in that case you have to use cache to get the image there and try to load image from there.For better know how to use it..use SDwebimage thats the nice way to do it and it is fast. You can read

  1. Lazy Loading

    2.paging enabled.

https://github.com/rs/SDWebImage

Need any further help.Happy to help you.

Upvotes: 0

MuhammadBassio
MuhammadBassio

Reputation: 1570

I am not sure why are you setting the frame when you start scrolling, but if I were in your place I would do the logic as per below:

-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
    // do nothing
}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

    int gallerypage = scrollView.contentOffset.x /scrollView.frame.size.width;
    CGFloat xoffset = 290 * gallerypage;
    [UIView animateWithDuration:0.5
                     animations:^{
                         scrollView.contentOffset = CGPointMake(xoffset, 0);
                     } 
                     completion:^(BOOL finished){
                         NSLog(@"Done!");
                     }];
}

Hope it helps.

Upvotes: 0

soryngod
soryngod

Reputation: 1827

I think that happens because your images are larger in size (MB) , and you fit them into that CGRect without resizing them that specific size, also it matters how many pictures you have loaded inside the scrollview , if you load many pictures it will take a lot of memory and it will slide slowly.

Upvotes: 0

CarlJ
CarlJ

Reputation: 9481

You should checkout SYPaginator (SYPaginator is a horizontal TableView with lazy loading and view recycling.)

Simple paging scroll view to make complicated tasks easier. We use this in several of the Synthetic apps including Hipstamatic, D-Series, and IncrediBooth.

If you need more perfomance you should give MSCachedAsyncViewDrawing a try:

Helper class that allows you to draw views (a)synchronously to a UIImage with caching for great performance.

Upvotes: 0

Edwin
Edwin

Reputation: 3802

You need to change your implementation for loading the images from a remote resource, thats where the biggest bottle neck lies.

I don't want to go into details but try to replace this line of code

[webview setImageWithURL:url placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

With something more c.p.u friendly. Use a caching mechanism that employs multi-threading, what you want to do is move the heavy lifting (Downloading remote images) to another thread.

SDWebImage does a perfect job at this https://github.com/rs/SDWebImage If you are a bit hard core, you can roll your own multi-threaded image downloader using

[NSURLConnection sendAsynchronousRequest:queue: completionHandler:] 

And do the image loading in the block, Or even better dispatch_async(queu, block)

Upvotes: 0

morph85
morph85

Reputation: 825

The two methods: scrollViewWillBeginDecelerating and scrollViewDidEndDecelerating contains two animation with different x position it is animated to:

frame.origin.x = frame.size.width-15*gallerypage;

and

frame.origin.x=gallerypage*290;

It is better if you could turn off either function: scrollViewWillBeginDecelerating or scrollViewDidEndDecelerating. Otherwise probably you should adjust the x position (must be in sync for both functions) it will be animated to.

Upvotes: 1

Bhavesh Nayi
Bhavesh Nayi

Reputation: 3656

if (i==0) {
            webview=[[UIImageView alloc]initWithFrame:CGRectMake(i*320, 0, 270, 440)];
        }
        else {
            webview=[[UIImageView alloc]initWithFrame:CGRectMake(i*320, 0, 270, 380)];
        }

Upvotes: 0

Related Questions