UITableView Scroll Lag - ios

I have a UITableView that loads content from a server.
All works fine and the content loads correctly, but when I scroll my UITableView lags a bit.
I created a method that downloads the content from a server, and I call this method in my viewDidLoad method, since it is the first thing that opens when I open the app.
I don't know if this is the best approach.
How I can avoid that? Here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Method that Loads the Content
[self retrieveData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Retorna o número de linhas pelo array de programacao.
return programacaoArray.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// ALTURA da TableViewCell
return 150;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"CellIdentifier";
ProgramacaoTableCell *cell = (ProgramacaoTableCell *)[self.tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[ProgramacaoTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
// Configure the Cell
Programacao *programacaoObject;
programacaoObject = [programacaoArray objectAtIndex:indexPath.row];
cell.atracaoImagem.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:programacaoObject.programacaoImagem]]];
cell.nomeLabel.text = programacaoObject.programacaoNome;
cell.dataLabel.text = programacaoObject.programacaoData;
cell.localLabel.text = programacaoObject.programacaoLocal;
return cell;
}
- (void) retrieveData
{
NSURL *url = [NSURL URLWithString:getDataURL];
NSData *data = [NSData dataWithContentsOfURL:url];
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
// SETUP programacaoArray
programacaoArray = [[NSMutableArray alloc] init];
// Loop throught do Array
for (int i = 0; i < jsonArray.count; i++) {
// Cria o PROGRAMACAO Objeto
NSString *pID = [[jsonArray objectAtIndex:i] objectForKey:#"id"];
NSString *pNome = [[jsonArray objectAtIndex:i] objectForKey:#"programacaoNome"];
NSString *pImagem = [[jsonArray objectAtIndex:i] objectForKey:#"programacaoImagem"];
NSString *pDescricao = [[jsonArray objectAtIndex:i] objectForKey:#"programacaoDescricao"];
NSString *pData = [[jsonArray objectAtIndex:i] objectForKey:#"programacaoData"];
NSString *pLocal = [[jsonArray objectAtIndex:i] objectForKey:#"programacaoLocal"];
NSString *pPrecos = [[jsonArray objectAtIndex:i] objectForKey:#"programacaoPrecos"];
// Add to the Array
[programacaoArray addObject:[[Programacao alloc] initWithNome:pNome andImagem:pImagem andDescricao:pDescricao andData:pData andLocal:pLocal andPrecos:pPrecos andID:pID]];
}
// RELOAD TABLE VIEW
[self.tableView reloadData];
}

There's a very obvious mistake you're making. You're loading the image synchronously (on the same thread, which in this case is the main thread), which is what's causing the lag. You should look into using AFNetworking's UIImageView category, which will load these images in the background for you.
You can download the AFNetworking library from here.

I think cause problem by code:
'cell.atracaoImagem.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:programacaoObject.programacaoImagem]]];
you can use SDWebImage framework, loading image

I think you should call the retrieveData function in viewWillAppear method instead of viewDidLoad

Related

Perform addition of values from each cell of tableview

I am working on a Shopping app where I add items in cart. Now I have to show the sub total amount where I need to perform addition of price of each item in table.
How can I pick values from each cell and add them?
Below is the code for tableview:
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [CartList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *cellData = [[[CartList objectAtIndex:indexPath.row] valueForKey:#"AddtoCartProductImageModel"] firstObject];
NSString *image=[cellData valueForKey:#"productimg"];
NSString *urlString = [NSString stringWithFormat:#"http://dealnxt.com/areas/user/productimage/%#", image];
NSURL *Url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:Url];
NSString *CellData = [[CartList objectAtIndex:indexPath.row] valueForKey:#"shortdescription"];
static NSString *simpleTableIdentifier = #"Cell";
CartTableViewCell *cell = (CartTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier forIndexPath: indexPath];
cell.proimg.image=[UIImage imageWithData:data];
cell.prlbl.lineBreakMode = NSLineBreakByWordWrapping;
cell.prlbl.numberOfLines = 0;
cell.prlbl.text=CellData;
cell.prprice.text=[NSString stringWithFormat: #"₹%#",[[CartList objectAtIndex:indexPath.row] valueForKey:#"price"]];
cell.quantity.text=[NSString stringWithFormat:#"%#",[[CartList objectAtIndex:indexPath.row] valueForKey:#"quantity"]];
NSString *string =[NSString stringWithFormat: #"%#",[[CartList objectAtIndex:indexPath.row] valueForKey:#"price"]];
int value = [string intValue];
for (int i=0; i<=[CartList count]; i++) {
int Total=0;
Total=+value;
NSLog(#"total:%d",Total);
}
return cell;
}
Where prprice is what I need to add.
// write this code somewhere where you fill the CartList variable value.
float tot;
for (int i = 0; i < [CartList count]; i++)
{
tot = tot + [[[CartList objectAtIndex:i] valueForKey:#"price"] floatValue];
// Do stuff...
}
NSLog("Total Cost : ₹ %.2f",tot);
We don't know what the class of the objects in your CartList array, but the code might look something like this:
double total = 0;
for (anItem in CartList) {
total += (double) anItem["price"];
}

TableView is not updating

I hope you guys help me in my code which is load data from a website. Let's start with the code:
-(void)viewDidLoad
{
[self loadDataFromUrl];
}
-(void)loadDataFromUrl {
NSString *myUrl = [NSString stringWithFormat:#"http://WebSite/PhpFiles/File.php"];
NSURL *blogURL = [NSURL URLWithString:myUrl];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization
JSONObjectWithData:jsonData options:0 error:&error];
for (NSDictionary *bpDictionary in dataDictionary) {
HotelObject *currenHotel = [[HotelObject alloc]initWithVTheIndex:
[bpDictionary objectForKey:#"TheIndex"] timeLineVideoUserName:
[bpDictionary objectForKey:#"timeLineVideoUserName"] timeLineVideoDetails:
[bpDictionary objectForKey:#"timeLineVideoDetails"] timeLineVideoDate:
[bpDictionary objectForKey:#"timeLineVideoDate"] timeLineVideoTime:
[bpDictionary objectForKey:#"timeLineVideoTime"] timeLineVideoLink:
[bpDictionary objectForKey:#"timeLineVideoLink"] timeLineVideoLikes:
[bpDictionary objectForKey:#"timeLineVideoLikes"] videoImage:
[bpDictionary objectForKey:#"videoImage"] timeDeviceToken:
[bpDictionary objectForKey:#"deviceToken"]];
[self.objectHolderArray addObject:currenHotel];
}
}
-(NSMutableArray *)objectHolderArray{
if(!_objectHolderArray) _objectHolderArray = [[NSMutableArray alloc]init];
return _objectHolderArray;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section
{
return [self.objectHolderArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
HotelObject *currentHotel = [self.objectHolderArray
objectAtIndex:indexPath.row];
cell.lblID.text = currentHotel.vvTheIndex;
cell.lblName.text = currentHotel.vvUserName;
cell.lblCity.text = currentHotel.vvVideoDate;
cell.lblAddress.text = currentHotel.vvVideoLikes;
return cell;
}
The above code is loading data from a Url and fill the TableView and this step working fine. The app has another ViewController which is DetailsView, in DetailsView users can update some info. When the user goes back to the TableView nothing happened (I mean the data still the same and not updated). I have tried to call the loadDataFromurl from ViewDidAppear but it does not work.
I did add:
[self.tableView reloadData];
But still the same result.
Her is also my NSObject code:
-(instancetype)initWithVTheIndex:(NSString *)vTheIndex
timeLineVideoUserName:(NSString *)vUserName
timeLineVideoDetails:(NSString *)vVideoDetails
timeLineVideoDate:(NSString *)vVideoDate
timeLineVideoTime:(NSString *)vVideoTime
timeLineVideoLink:(NSString *)vVideoLink
timeLineVideoLikes:(NSString *)vVideoLikes
videoImage:(NSString *)vVideoImage
timeDeviceToken:(NSString *)vDeviceToken {
self = [super init];
if(self){
self.vvTheIndex = vTheIndex;
self.vvUserName = vUserName;
self.vvVideoDetails = vVideoDetails;
self.vvVideoDate = vVideoDate;
self.vvVideoTime = vVideoTime;
self.vvVideoLink = vVideoLink;
self.vvVideoLikes = vVideoLikes;
self.vvVideoImage = vVideoImage;
self.vvDeviceToken = vDeviceToken;
}
return self;
}
My question is: How can I update the TableView when moving from DetailsView or even when I pull to refresh.
Thanks in advance
You are not properly reloading the data source of your UITableView.
Assuming the remote URL is getting updated with the new data, and the issue is only reloading the TableView, make sure you add your [self.tableView reloadData] AFTER loadDataFromUrl has finished.
The reloadData method will always refresh the table's content, so either it's not being called at the right time or you are not updating self.objectHolderArray. (You can debug that by setting a breakpoint after calling loadDataFromUrl after the update.)
on viewDidLoad lifecycle first [self.tableView reloadData] reload tableview then another work.

UICollectionView Displays empty

Hi in my application in trying display the Flickr images in my UICollectionView but it shows a empty View Control
My code for display the Flickr images.
{
NSMutableArray *photoURLs;
NSMutableArray *photoSetNames;
NSMutableArray *photoids;
}
viewDidLoad code.
- (void)viewDidLoad
{
[super viewDidLoad];
photoURLs = [[NSMutableArray alloc] init];
photoSetNames = [[NSMutableArray alloc] init];
photoids = [[NSMutableArray alloc] init];
[self loadFlickrPhotos];
[self.collectionview reloadData];
}
- (void)loadFlickrPhotos {
NSString *urlString = [NSString stringWithFormat:#"https://www.flickr.com/services/rest/?method=flickr.photosets.getPhotos&format=json&api_key=a6a0c7d5efccffc285b0fe5ee1d938e3&photoset_id=72157644758906604&per_page=10&nojsoncallback=1",nil];
NSLog(#"the url string==%#",urlString);
NSURL *url = [NSURL URLWithString:urlString];
NSString *jsonString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSLog(#"the str==%#",jsonString);
NSDictionary *results = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
NSArray *photosets = [[results objectForKey:#"photosets"] objectForKey:#"photoset"];
for (NSDictionary *photoset in photosets) {
NSString *title = [[photoset objectForKey:#"title"] objectForKey:#"_content"];
NSLog(#"title==%#",title);
[photoSetNames addObject:(title.length > 0 ? title : #"Untitled")];
NSString *primary = [photoset objectForKey:#"primary"];
NSString *server = [photoset objectForKey:#"server"];
NSString *secret = [photoset objectForKey:#"secret"];
NSString *farm = [photoset objectForKey:#"farm"];
NSString *urlstr=[NSString stringWithFormat:#"http://farm%#.staticflickr.com/%#/%#_%#.jpg",farm,server,primary,secret];
NSLog(#"your photo id==%#",urlstr);
[photoids addObject:urlstr];
}
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [photoids count];
}
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier =#"Cell";
imggpolitical *cell=(imggpolitical *) [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath: indexPath];
cell.imageview.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",[photoids objectAtIndex:indexPath.row]]]]];
return cell;
}
I have used the above to display the Flickr images in UICollectionView but its coming as a empty view please tell me how to resolve this issue.
Thanks.
At the end of -(void)loadFlickrPhotos method, call reloadData on your UICollectionView. You need to tell UICollectionView to refresh its data.
Try [self.collectionview reloadData]
I don't see that you're assigning a delegate or data source. Or for that matter, created your UICollectionView.

how to do multi-threading to load the image faster to tableView

-(void)viewDidLoad {
[super viewDidLoad]; // Do any additional setup after loading the view from its nib. self.navigationItem.title = #"New Arrivals";
[super viewDidLoad]; idsArray=[[NSMutableArray alloc]init]; namesArray=[[NSMutableArray alloc]init]; imagesArray=[[NSMutableArray alloc]init];
// create the URL we'd like to query
NSURL *myURL = [[NSURL alloc]initWithString:#"http://www.bikrionline.com/nwarvl-json.php"];
// we'll receive raw data so we'll create an NSData Object with it NSData *myData = [[NSData alloc]initWithContentsOfURL:myURL];
// now we'll parse our data using NSJSONSerialization if ([myData length]>0) { id myJSON = [NSJSONSerialization JSONObjectWithData:myData options:NSJSONReadingMutableContainers error:nil]; NSArray *jsonArray = (NSArray *)myJSON; for (int i=0 ; i<[jsonArray count] ; i++) { NSMutableString *urlString = [[NSMutableString alloc]initWithString:#"http://www.bikrionline.com/products/zmphotos/"]; NSString * name = [[[jsonArray objectAtIndex:i]objectForKey:#"prodname"]retain]; [namesArray addObject:name]; [idsArray addObject:[[jsonArray objectAtIndex:i]objectForKey:#"prodid"]]; [urlString appendString:[[jsonArray objectAtIndex:i]objectForKey:#"imageurl"]]; UIImage *imageObj = [self getImageFromUrl:urlString]; urlString = nil; [imagesArray addObject:imageObj]; } }
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
CustomCellView *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *arrNib = [[NSBundle mainBundle] loadNibNamed:#"CustomCellView" owner:self options:nil];
cell = [arrNib objectAtIndex:0];
}
cell.imgName.text = [namesArray objectAtIndex:indexPath.row];
cell.custImageView.image=[imagesArray objectAtIndex:indexPath.row];
return cell;
}
You can use some Lib like SDWebImage or Afnetworking. Libs support lazy load image and auto cache this image.
All you need to do:
[cell.imageView setImageWithURL:[NSURL URLWithString:#"url of image"]
placeholderImage:nil];
This is looking a similar question like lazy loading of an image: Check iOS lazy-loading of table images and Loading images on scrollview using lazy loading
for your answer

Facebook, iOS SDK

I am currently making a Facebook application for iOS that pulls the profile feed and puts it in a UITableView.
Right Now When the View Loads:
[facebook requestWithGraphPath:#"me/feed" andDelegate:self];
and in -(void)request:(FBRequest *)request didLoad:(id)result, i have:
NSArray *messagesFBData = [result objectForKey:#"data"];
NSMutableArray *friendIds = [NSMutableArray arrayWithCapacity:messagesFBData.count];
NSMutableArray *fromData = [NSMutableArray arrayWithCapacity:messagesFBData.count];
NSMutableArray *imagesLocal = [NSMutableArray arrayWithCapacity:messagesFBData.count];
for (int x = 0; x < messagesFBData.count; x++) {
if ([(NSDictionary *)[messagesFBData objectAtIndex:x] objectForKey:#"message"] != nil) {
[friendIds addObject:[((NSDictionary*)[messagesFBData objectAtIndex:x]) objectForKey:#"message"]];
NSLog(#"loop Log: %#", [(NSDictionary *)[messagesFBData objectAtIndex:x] objectForKey:#"message"]);
[fromData addObject:[((NSDictionary*)[messagesFBData objectAtIndex:x]) objectForKey:#"from"]];
NSLog(#"%#", [((NSDictionary*)[messagesFBData objectAtIndex:x]) objectForKey:#"from"] );
NSDictionary *fromDataDictionary = [fromData objectAtIndex:x];
[imagesLocal addObject:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture", [fromDataDictionary objectForKey:#"id"]]]]]];
NSLog(#"facebook ID: %#", [fromDataDictionary objectForKey:#"id"]);
} else
{
NSLog(#"Nil Called");
}
}
// don't forget to call loadData for your tableView
messages = friendIds;
images = imagesLocal;
NSLog(#"Equalized");
self.facebookTableView.delegate = self;
NSLog(#"Delegate Set");
[facebookTableView reloadData];
images is a global array, so i can access it in -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath.
so in -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath, i have:
NSLog(#"Cell For Row Called");
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:#"messageCell"];
NSString *story = [messages objectAtIndex:indexPath.row];
cell.textLabel.text = story;
UIImage *image = [images objectAtIndex:indexPath.row];
cell.imageView.image = image;
cell.alpha = 1;
return cell;
So the question I am having a horrible time with is when a user posts a picture or video on the wall, how do i handle that? I would like to display the image/video in the tableview itself. Right Now, it just crashes. Any help would be greatly appreciated.
Thanks,
Virindh Borra
At what point is it crashing? Did you place any breakpoints in the code? When you add the UIImage to the imagesLocal array, are you the path at "https://graph.facebook.com/%#/picture" contains a valid image?

Resources