Reputation: 175
Now I'm working with uitableview which contains user image set on uibutton, recorded video play on mpmovieplayercontroller like as vine app.
Here my problem is uitableview doesn't scrolling smoothly when goes from one row to another row.
I don't know why this happen. Anybody know the reason give some guidance for how to resolve that kind of issue.
Here I get data from web service.
-(void)feedwebservice
{
NSString *myurl1=[NSString stringWithFormat:@"http://demo.xyz.com/client/vine-clone/feed/home_feed?user_id=%@&start=%d",AppDelegate.check,navigate];
NSString *theurl1=[myurl1 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *theRequest1=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:theurl1]cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSHTTPURLResponse *response;
NSError* error12;
NSData *data1=[NSURLConnection sendSynchronousRequest:theRequest1 returningResponse:&response error:&error12];
NSString *strResponse1=[[NSString alloc]initWithData:data1 encoding:NSUTF8StringEncoding];
NSMutableString* responseString = [NSMutableString stringWithString:strResponse1];
SBJSON *parser = [[SBJSON alloc] init];
NSDictionary *dic1 = [parser objectWithString:responseString error:nil];
for(NSDictionary *subDic in dic1)
{
obj=[[DataSet alloc]init];
obj.data1=[subDic objectForKey:@"channel"];
obj.data2=[subDic objectForKey:@"followers"];
obj.data3=[subDic objectForKey:@"following"];
obj.data4=[subDic objectForKey:@"fullname"];
obj.data5=[subDic objectForKey:@"post_private"];
obj.data6=[subDic objectForKey:@"post_sensitive"];
obj.data7=[subDic objectForKey:@"profile_image"];
obj.data8=[subDic objectForKey:@"status"];
obj.data9=[subDic objectForKey:@"title"];
obj.data10=[subDic objectForKey:@"total_like"];
obj.data11=[subDic objectForKey:@"total_vine"];
obj.data12=[subDic objectForKey:@"user_id"];
obj.data13=[subDic objectForKey:@"user_like"];
obj.data14=[subDic objectForKey:@"user_vine"];
obj.data15=[subDic objectForKey:@"video_created_date"];
obj.data16=[subDic objectForKey:@"video_id"];
obj.data17=[subDic objectForKey:@"video_name"];
[feedarr addObject:obj];
}
//NSLog(@"feedpage count = %u",[feedarr count]);
[videotable reloadData];
[pullToRefreshManager_ tableViewReloadFinished];
}
Data used on uitableview cell for row at index path
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
/*if(cell == nil)
{
}*/
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
obj=[feedarr objectAtIndex:indexPath.row];
profileimgbtn = [UIButton buttonWithType:UIButtonTypeCustom];
[profileimgbtn setFrame:CGRectMake(10, 280, 50, 40)];
[profileimgbtn setBackgroundColor:[UIColor clearColor]];
[profileimgbtn setBackgroundImage:[UIImage imageNamed:@"Placeholder.png"] forState:UIControlStateNormal];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
obj.data7 = [obj.data7 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSURL *imageURL = [NSURL URLWithString:obj.data7];
NSURLRequest *request = [NSURLRequest requestWithURL:imageURL];
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
UIImage *image = [[UIImage alloc] initWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
[profileimgbtn setBackgroundImage:image forState:UIControlStateNormal];
});
});
[cell addSubview:profileimgbtn];
playerview = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 300, 250)];
[playerview setBackgroundColor:[UIColor orangeColor]];
[cell addSubview:playerview];
obj.data17 = [obj.data17 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSURL *contentURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@",obj.data17]];
mc = [[MPMoviePlayerController alloc] initWithContentURL:contentURL];
mc.shouldAutoplay = YES;
mc.controlStyle = MPMovieControlStyleNone;
mc.contentURL = contentURL;
[mc prepareToPlay];
mc.repeatMode=MPMovieRepeatModeOne;
mc.view.frame = playerview.bounds;
[mc setScalingMode:MPMovieScalingModeFill];
[mc play];
[playerview addSubview:mc.view];
//Get the image from the currentPlaybackTime to set it above the player
thumbnail = [mc thumbnailImageAtTime:[mc currentPlaybackTime] timeOption:MPMovieTimeOptionNearestKeyFrame];
thumbnailView = [[UIImageView alloc] initWithFrame:mc.view.frame];
[thumbnailView setImage:thumbnail];
[thumbnailView setContentMode:UIViewContentModeScaleToFill];
thumbnailView.clipsToBounds = YES;
[playerview addSubview:thumbnailView];
singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleRollTap:)];
[singleFingerTap setDelegate:self];
singleFingerTap.numberOfTouchesRequired=1;
singleFingerTap.numberOfTapsRequired=1;
[mc.view addGestureRecognizer:singleFingerTap];
self.moviePlayerController = mc;
playerActivityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
playerActivityIndicator.frame = CGRectMake(140, 110, 25, 25);
[playerActivityIndicator startAnimating];
[playerview addSubview:playerActivityIndicator];
[self performSelector:@selector(spinnerhide) withObject:nil afterDelay:5.0];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
return cell;
}
Upvotes: 1
Views: 1035
Reputation: 1415
You can add the EgoImagebuton
file from the Internet: https://github.com/enormego/EGOImageLoading
Then, use egoimagebuton
instead of UIImageView
.
Upvotes: 2
Reputation: 19114
In addition to reusing the cell as suggested in other answers, you also need to ensure that in your completion handler the cell that your are assigning the image will be explicitly obtained again by sending the table view a corresponding message which returns the cell based on the indexPath.
The reason you need to do this, is that once you reuse cells, and once your completion handler gets executed, the cell isn't associated anymore to the indexPath as it was before.
Thus, in your completion handler re-obtain the cell based on the indexPath:
dispatch_async(dispatch_get_main_queue(), ^{
MyTableViewCell* cell = (MyTableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
[cell.addProfileImagegButton setBackgroundImage:image forState:UIControlStateNormal];
});
Here, it is assumed you have subclassed the a UITableViewCell
which has a property profileImagegButton
.
Also, if it happens that the cell isn't visible anymore, cellForRowAtIndexPath:
returns nil
.
A complete solution however, requires that you implement an image cache, and also prevent to load a URL when there is currently a request with the same URL pending. You need to check the cache whether it has an image before you set the placeholder image.
Upvotes: 0
Reputation: 25697
You seem to have commented out cell reuse - which is an amazing performance-saving feature, used to limit the number of cells created and thus the amount the system is taxed.
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
obj=[feedarr objectAtIndex:indexPath.row];
...
Upvotes: 1
Reputation: 4259
It's really bad, you should not create cell every time:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
/*if(cell == nil)
{
}*/
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
Should be:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
Upvotes: 0