this question had been mentioned many time here but my case is slightly different what i am doing that there is a two UITableViewController inside UITabBarController when i switch to second UITableViewController the cellForRowAtIndextPath method is not fired to fill the UITableViewController with the data that are pulled from my server using AFNetworking after searching for many solution over the internet all the question that i found does not include UITabBarController such as
question 1 , question 2, question 3, question 4, question 5,
here is the code that i am trying to use :
#import "newsAndEventTableViewController.h"
#import "SplashViewController.h"
#import "sharedVariables.h"
#import"AFNetworking.h"
#import "UIWebView+AFNetworking.h"
#import "SDWebImageCompat.h"
#import "SDWebImageDownloaderOperation.h"
#import "SDWebImageDownloader.h"
#import "MyGeeksTableViewController.h"
#import "geeksEvent.h"
#interface newsAndEventTableViewController ()
{
NSMutableArray *events;
geeksEvent *eventObject;
NSMutableArray *listOfEventsObjects;
}
#end
#implementation newsAndEventTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate = self;
UIImage *image = [UIImage imageNamed:#"image.png"];
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:image];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [events count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:#"http://myserver.com/get.php" parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {
// NSArray *products = [jsonDict objectForKey:#"images"];
// [products enumerateObjectsUsingBlock:^(id obj,NSUInteger idx, BOOL *stop){
// // NSString *productIconUrl = [obj objectForKey:#"imageUrl"];
//
// }];
//
NSLog(#"the response is: %#",responseObject);
events = [responseObject objectForKey:#"events"];
for (int i = 0; i < [events count];i++) {
eventObject = [events objectAtIndex:i];
[listOfEventsObjects addObject:eventObject];
}
}
failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(#"Error: %#", error);
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Error"
message:#"pls check your internet connection"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"retry"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Handel your yes please button action here
}];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:#"No, Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Handel no, thanks button
}];
[alert addAction:yesButton];
[alert addAction:noButton];
[self presentViewController:alert animated:YES completion:nil];
}];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Display recipe in the table cell
geeksEvent *event = [events objectAtIndex:indexPath.row];
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [UIImage imageNamed:#"placeholderimage"];
UILabel *eventTitle = (UILabel *)[cell viewWithTag:200];
eventTitle.text = event.eventTitle;
NSLog(#"the event title is: %#",event.eventTitle);
UILabel *eventDesc = (UILabel *)[cell viewWithTag:300];
eventDesc.text = event.eventShortDiscription;
// Assign our own background image for the cell
// UIImage *background = [self cellBackgroundForRowAtIndexPath:indexPath];
// UIImageView *cellBackgroundView = [[UIImageView alloc] initWithImage:background];
// cellBackgroundView.image = background;
// cell.backgroundView = cellBackgroundView;
return cell;
}
/*
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<##"reuseIdentifier"#> forIndexPath:indexPath];
// Configure the cell...
return cell;
}
*/
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
The code inside the success block of the AFNetworking request is called asynchronously and that's why there's no data when displaying the tableView.
As a suggestion, you may want to move the AFNetworking request outside the tableView:cellForRowAtIndexPath: method (ex.: viewDidLoad) because this will trigger a request every time the app wants to display a cell, making the app unresponsive and consume the user bandwidth.
So using the suggestions above, the code will be:
#import "newsAndEventTableViewController.h"
#import "SplashViewController.h"
#import "sharedVariables.h"
#import"AFNetworking.h"
#import "UIWebView+AFNetworking.h"
#import "SDWebImageCompat.h"
#import "SDWebImageDownloaderOperation.h"
#import "SDWebImageDownloader.h"
#import "MyGeeksTableViewController.h"
#import "geeksEvent.h"
#interface newsAndEventTableViewController ()
{
NSMutableArray *events;
geeksEvent *eventObject;
NSMutableArray *listOfEventsObjects;
}
#end
#implementation newsAndEventTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate = self;
UIImage *image = [UIImage imageNamed:#"image.png"];
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:image];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:#"http://myserver.com/get.php" parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {
NSLog(#"the response is: %#",responseObject);
events = [responseObject objectForKey:#"events"];
for (int i = 0; i < [events count];i++) {
eventObject = [events objectAtIndex:i];
[listOfEventsObjects addObject:eventObject];
}
// Calling reload data after request is done
[self.tableView reloadData];
}
failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(#"Error: %#", error);
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Error"
message:#"pls check your internet connection"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"retry"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Handel your yes please button action here
}];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:#"No, Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Handel no, thanks button
}];
[alert addAction:yesButton];
[alert addAction:noButton];
[self presentViewController:alert animated:YES completion:nil];
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [events count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Display recipe in the table cell
geeksEvent *event = [events objectAtIndex:indexPath.row];
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [UIImage imageNamed:#"placeholderimage"];
UILabel *eventTitle = (UILabel *)[cell viewWithTag:200];
eventTitle.text = event.eventTitle;
NSLog(#"the event title is: %#",event.eventTitle);
UILabel *eventDesc = (UILabel *)[cell viewWithTag:300];
eventDesc.text = event.eventShortDiscription;
// Assign our own background image for the cell
// UIImage *background = [self cellBackgroundForRowAtIndexPath:indexPath];
// UIImageView *cellBackgroundView = [[UIImageView alloc] initWithImage:background];
// cellBackgroundView.image = background;
// cell.backgroundView = cellBackgroundView;
return cell;
}
#end
Related
I have an issue with reloading a UITableView when calling from other viewcontroller. I have called a service from viewcontroller.m and the results are displayed in tableviewcontroller.m. Here is my problem, I have a button in UITableViewCell, when clicked on a button, the table should be reloaded or refreshed.
Below is my code:
viewController.m
NSString * post = [[NSString alloc]initWithFormat:#"country=%#&state=%#&userId=%#",_txtSearchField.text,UserId];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"url"]];
tableviewcontroller.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
customCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(!cell)
{
cell = [[customCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSArray *arr=[[profileArr objectAtIndex:indexPath.row] allKeys];
cell.lblAge.text = [[[profileArr objectAtIndex:indexPath.row] valueForKey:key] valueForKey:#"Age"];
cell.lblLocation.text = [[[profileArr objectAtIndex:indexPath.row] valueForKey:key] valueForKey:#"Address"];
cell.lblProfession.text = [[[profileArr objectAtIndex:indexPath.row] valueForKey:key] valueForKey:#"Occupation"];
}
-(void)buttonclick:(id)sender
{
UIButton *btn = sender;
NSArray *arr=[[profileArr objectAtIndex:btn.tag] allKeys];
NSString *key=[arr objectAtIndex:0];
NSMutableDictionary *userDict=[[profileArr objectAtIndex:btn.tag] objectForKey:key];
NSString *str = [userDict objectForKey:#"UserId"];
[self callbuttonService:str];
}
-(void)callbuttonService:(NSString *)OtherUserId
{
//service is called
}
#pragma mark - MRConnection Delegate Methods
- (void)jsonData:(NSDictionary *)jsonDict
{
[SVProgressHUD dismiss];
NSMutableArray *jsonArr1;
jsonArr1=[jsonDict objectForKey:#"DataTable"];
if (![jsonArr1 isEqual:[NSNull null]]) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Employee" message:#"Sucess" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:ok];
[self presentViewController:alertController animated:YES completion:nil];
[alertController.view setTintColor:[UIColor blackColor]];
}
else{
[SVProgressHUD showErrorWithStatus:#"Something went wrong!"];
}
}
According to your question, you have call service in viewcontroller.m file and you want to reload tableview in tableviewcontroller.m file. Please try this. keep coding.
viewController.m
-(void)callbuttonService:(NSString *)OtherUserId
{
//service is called
}
#pragma mark - MRConnection Delegate Methods
- (void)jsonData:(NSDictionary *)jsonDict
{
[SVProgressHUD dismiss];
NSMutableArray *jsonArr1;
jsonArr1=[jsonDict objectForKey:#"DataTable"];
if (![jsonArr1 isEqual:[NSNull null]]) {
NSDictionary *DictionaryData = [[NSDictionary alloc]init];
[DictionaryData setValue:jsonArr1 forKey:#"data"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"tableReload" object:nil userInfo:DictionaryData];
}
else{
[SVProgressHUD showErrorWithStatus:#"Something went wrong!"];
}
}
tableviewcontroller.m
-(void)viewDidLoad() {
super.viewDidLoad()
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(tableReloadNotification:) name:#"tableReload" object:nil];
}
- (void) tableReloadNotification:(NSNotification *) notification {
NSDictionary *info = notification.userInfo;
if (info != nil) {
NSMutableArray *jsonArr1 = [info valueForKey:#"data"];
tableview.reloadData();
}
}
You can use NSNotificationCenter for reload table view from another class. When your web service respond successfully then post your local notification.
Have you tried just calling [tableView reloadData]?
Also I fail to see how you add a button to your default UITableViewCell. Maybe you want this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
// check if correct cell was tapped
if (indexPath.section == 0 && indexPath.row == 0)
{
[tableView reloadData];
}
}
When you implement this method, it will be called whenever you tap a UITableViewCell, you won't need a button or something.
Of course, you're free to bind the [tableView reloadData] to any other action in your app, e. g. a button in the toolbar or something.
I had a problem with tableview which is when the table first shows everything looks great but if I scroll up and and down, NSLog(#"page name : %#", cell.pageName.text); output value will be duplicate and it will cause the scrolling to be lagged. This is my code :
#import "HomeTVC.h"
#import "facebook.h"
#import "HomeTVCell.h"
#import <SDWebImage/UIImageView+WebCache.h>
#interface HomeTVC ()<UITableViewDataSource, UITableViewDelegate>
{
NSDictionary *userPageLikesParams;
NSArray *pagesInfo;
}
#end
#implementation HomeTVC
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate = self;
self.tableView.dataSource = self;
facebook *fb = [[facebook alloc] init];
userPageLikesParams = #{#"fields": #"about,name,created_time,picture",#"limit": #"10"} ;
[fb getUserPagelikes:userPageLikesParams completionHandler:^(NSDictionary *pagesResult) {
if (pagesResult != nil) {
pagesInfo = pagesResult[#"data"];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"table count : %d", (int)pagesInfo.count);
if (pagesInfo == nil) {
return 0;
} else {
return pagesInfo.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
HomeTVCell *cell = (HomeTVCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[HomeTVCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSURL *imageURL = [NSURL URLWithString:[pagesInfo[indexPath.row] valueForKeyPath:#"picture.data.url"]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
// UIImage *pageProfileImage = [UIImage imageWithData:imageData];
// NSLog(#"pages info : %#", pagesInfo[indexPath.row]);
// NSLog(#"pages info image URL : %#", imageURL);
// cache the image using sdwebimage
cell.pageProfilePic.layer.backgroundColor=[[UIColor clearColor] CGColor];
cell.pageProfilePic.layer.borderWidth= 2.0;
cell.pageProfilePic.layer.masksToBounds = YES;
cell.pageProfilePic.layer.borderColor=[[UIColor whiteColor] CGColor];
cell.pageProfilePic.layer.cornerRadius= 30.0;
[cell.pageProfilePic sd_setImageWithURL:imageURL placeholderImage:[UIImage imageNamed:#"placeholder.jpg"]];
//cell.pageProfilePic.image = pageProfileImage;
cell.pageName.text = pagesInfo[indexPath.row][#"name"];
NSLog(#"page name : %#", cell.pageName.text);
return cell;
}
Thanks in advance.
I use Xcode 6.2, and swift and this particular class with which I am having issue is in ObjectiveC. I am using storyboard, a tabcontroller, and one of the tabs calls thehistoryViewController` which has a table view. In iOS7, when I click on the history tabBarButton, the table view appears with its data.
In iOS8, when I click on history tabBarButton, the table view doesn't appear. If I click on some other tabBarButton, and then again select the history tabBarButton, the table view properly appears with its data.
#import "historyListViewController.h"
#import "QRdatabase.h"
#import "qrdbinfo.h"
#import "historyDetailViewController.h"
#import <UIKit/UIKit.h>
#import "SDWebImage/UIImageView+WebCache.h"
#import "UIImageView+WebCache.h"
#implementation historyListViewController
#synthesize details = _details;
#synthesize qrInfos = _qrInfos;
#synthesize segmentchange;
- (IBAction)valid_in_seg:(id)sender
{
if (segmentchange.selectedSegmentIndex == 0)
{ self.qrInfos = [QRdatabase database].qrdbInfos;
[self.tablelist reloadData];
}
else
{
self.qrInfos = [QRdatabase database].inqrdbInfos;
}
[self.tablelist reloadData];
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// Scroll table view to the last row
if (_shouldScrollToLastRow)
{
_shouldScrollToLastRow = NO;
[self.tablelist setContentOffset:CGPointMake(0, CGFLOAT_MAX)];
}
[self.tablelist reloadData];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tablelist reloadData];
UIImage *myImage =[UIImage imageNamed:#"logo_white_38.png"];
UIImageView *myImageView = [[UIImageView alloc] initWithImage:myImage];
[myImageView setFrame:CGRectMake(0, 0, 38, 38)];
self.navigationItem.titleView = myImageView;
self.navigationController.navigationBar.backgroundColor = [UIColor redColor];
segmentchange.tintColor = [UIColor redColor];
_shouldScrollToLastRow = YES;
if (segmentchange.selectedSegmentIndex == 0)
{
self.qrInfos = [QRdatabase database].qrdbInfos;
[self.tablelist reloadData];
}
else
{
self.qrInfos = [QRdatabase database].inqrdbInfos;
[self.tablelist reloadData];
}
self.tablelist.delegate = self;
self.tablelist.dataSource = self;
[self.view addSubview:self.tablelist];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (segmentchange.selectedSegmentIndex == 0)
{
self.qrInfos = [QRdatabase database].qrdbInfos;
[self.tablelist reloadData];
}
else
{
self.qrInfos = [QRdatabase database].inqrdbInfos;
[self.tablelist reloadData];
}
[self.tablelist reloadData];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
/*- (void)viewDidUnload {
self.qrInfos = nil;
self.details = nil;
}*/
#pragma mark Table view methods
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 10;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{ if (segmentchange.selectedSegmentIndex == 0)
{
return 80;
}
else
return 120;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_qrInfos count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (segmentchange.selectedSegmentIndex == 0)
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tablelist dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];}
qrdbinfo *info = [_qrInfos objectAtIndex:indexPath.row];
cell.textLabel.text = info.qr_code;
cell.detailTextLabel.text = [NSString stringWithFormat:#"Date: %#", info.date];
CGSize itemSize = CGSizeMake(30, 30);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[cell.imageView.image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:info.img]
placeholderImage:[UIImage imageNamed:#"img_not_available.png"]];
return cell;
}
else
{
static NSString *CellIdentifier = #"Cell2";
UITableViewCell *cell = [self.tablelist dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
qrdbinfo *info = [_qrInfos objectAtIndex:indexPath.row];
cell.textLabel.text = info.qr_code;
cell.detailTextLabel.text = [NSString stringWithFormat:#"Date: %#", info.date];
return cell;
}
// return cell;
}
- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void (^)(BOOL succeeded, UIImage *image))completionBlock
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
UIImage *image = [[UIImage alloc] initWithData:data];
completionBlock(YES,image);
} else{
completionBlock(NO,nil);
}
}];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(segmentchange.selectedSegmentIndex == 0)
{
qrdbinfo *info = [_qrInfos objectAtIndex:indexPath.row];
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"Main"
bundle:nil];
historyDetailViewController * vc = [sb instantiateViewControllerWithIdentifier:#"detail"];
vc.hidesBottomBarWhenPushed = YES;
vc.qrId = info.uniqueId;
[self.navigationController pushViewController:vc animated:YES];
}
else
{
UIAlertView *alerts = [[UIAlertView alloc] initWithTitle:#" Data Unavailable" message:#"No data available for invalid scans" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil, nil, nil];
[alerts show];
}
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
qrdbinfo *info = [_qrInfos objectAtIndex:indexPath.row];
[self.qrInfos removeObjectAtIndex:indexPath.row];
[self.tablelist deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
if(segmentchange.selectedSegmentIndex == 0)
{
// Delete the row from the data source
[[QRdatabase database] deleterow:info.uniqueId];
}
else
{
[[QRdatabase database] deleteinvalidrow:info.uniqueId];
}
[self.tablelist reloadData ];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
#end
I'm working on a sharing extension to simply grab a link, choose a few names to share it to, and Share. The data layer isn't added yet, only the UI to display some names in a tableview (using a custom cell) and I'm pulling in the shared URL from the extension context. All of the code in the VC is below. All views are set up in the Storyboard. Two UIButtons, Two UILabels, One TableView and a UIView to hold it all, so I can easily round the corners.
The issue I'm having is that the _linkLabel that I'm using the display the URL doesn't visually update for nearly 10 seconds! What.In.The.World. What I'm a doing here that's causing this?
I'm logging out the URL in the callback from hasItemConformingToTypeIdentifier and it happens as soon as the extension appears, but doesn't update the label??!! Helps. Please.
#import "ShareViewController.h"
#import "UserCell.h"
#interface ShareViewController ()
#end
#implementation ShareViewController
- (void)viewDidLoad{
self.view.alpha = 0;
_friends = [#[#"Ronnie",#"Bobby",#"Ricky",#"Mike"] mutableCopy];
_containerView.layer.cornerRadius = 6.f;
_selectedIndexPaths = [[NSMutableArray alloc] init];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[UIView animateWithDuration:0.5 animations:^{
self.view.alpha = 1;
}];
}
- (void)viewDidAppear:(BOOL)animated{
//pull the URL out
NSExtensionItem *item = self.extensionContext.inputItems[0];
NSItemProvider *provider = item.attachments[0];
if ([provider hasItemConformingToTypeIdentifier:#"public.url"]) {
[provider loadItemForTypeIdentifier:#"public.url" options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
NSURL *url = (NSURL*)item;
_linkLabel.text = url.absoluteString;
NSLog(#"Link: %#", url.absoluteString);
}];
}
else{
NSLog(#"No Link");
}
}
#pragma mark - UITableView Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UserCell *cell = (UserCell*)[tableView cellForRowAtIndexPath:indexPath];
if([_selectedIndexPaths containsObject:indexPath]){
[_selectedIndexPaths removeObject:indexPath];
cell.selected = NO;
}
else{
cell.selected = YES;
[_selectedIndexPaths addObject:indexPath];
}
NSLog(#"Share to %i friends", (int)[_selectedIndexPaths count]);
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
//Later, calc height based on text in comment
return 44;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [_friends count];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"UserCell";
UserCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[UserCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.selected = ([_selectedIndexPaths containsObject:indexPath]) ? YES : NO;
cell.nameLabel.text = [_friends objectAtIndex:indexPath.row];
return cell;
}
- (IBAction)dismiss {
[UIView animateWithDuration:0.34 animations:^{
self.view.alpha = 0;
} completion:^(BOOL finished) {
[self.extensionContext completeRequestReturningItems:nil completionHandler:nil];
}];
}
#end
Delays in updates to UI elements is a classic sign of trying to update the UI from outside the main queue. Which is what is happening here. You have this:
[provider loadItemForTypeIdentifier:#"public.url" options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
NSURL *url = (NSURL*)item;
_linkLabel.text = url.absoluteString;
NSLog(#"Link: %#", url.absoluteString);
}];
Except that NSItemProvider does not guarantee that the completion handler will be called on the same queue that you started on. You're almost guaranteed to be on a different queue here, so you're getting this weird delay. You need to dispatch back to the main queue to perform the update:
[provider loadItemForTypeIdentifier:#"public.url" options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSURL *url = (NSURL*)item;
_linkLabel.text = url.absoluteString;
NSLog(#"Link: %#", url.absoluteString);
});
}];
I have new data that I wish to put in my tableView, can you please help me with this. Currently mt table is populated with greekLetters and imageNames. On button click I wish to put new data in the table: greekLetters2
#interface ViewController2 ()
#end
#implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
self.greekLetters = #[#"BigBen",#"Colosseum",#"EiffelTower",#"GreatWallOfChina",#"StatueofLiberty",#"StBasils",#"Stonehenge",#"TajMahal",#"TowerOfPisa"];
self.imageNames = #[#"BigBen.jpg",#"Colosseum.jpg",#"EiffelTower.jpg",#"GreatWallOfChina.jpeg",#"StatueofLiberty.jpg",#"StBasils.jpg",#"Stonehenge.jpg",#"TajMahal.jpg",#"TowerOfPisa.jpg"];
self.greekLetters2 = #[#"BigBen2",#"Colosseum2",#"EiffelTower2",#"GreatWallOfChina2",#"StatueofLiberty2",#"StBasils2",#"Stonehenge2",#"TajMahal2",#"TowerOfPisa2"];
self.imageNames2 = #[#"BigBen2.jpg",#"Colosseum2.jpg",#"EiffelTower2.jpg",#"GreatWallOfChina2.jpeg",#"StatueofLiberty.jpg",#"StBasils2.jpg",#"Stonehenge2.jpg",#"TajMahal2.jpg",#"TowerOfPisa2.jpg"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.greekLetters count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *SimpleIdentifier = #"SimpleIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:SimpleIdentifier];
}
UIImage *image = [UIImage imageNamed:self.imageNames[indexPath.row]];
cell.imageView.image = image;
cell.textLabel.text = self.greekLetters[indexPath.row];
cell.textLabel.font = [UIFont boldSystemFontOfSize:30];
if (indexPath.row < 3)
{
cell.detailTextLabel.text = #"A";
}
else
{
cell.detailTextLabel.text = #"B";
}
return cell;
}
-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0)
{
return nil;
}
else
{
return indexPath;
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *rowValue = self.greekLetters[indexPath.row];
NSString *message = [[NSString alloc] initWithFormat:#"You selsected %#!",rowValue];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Row Selected" message:message delegate:nil cancelButtonTitle:#"Yes" otherButtonTitles:nil, nil];
[alert show];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 70;
}
- (IBAction)SwitchTable:(id)sender
{
//repapulate
}
#end
The easiest way is to switch the two array when the button is pressed. greekLetters has to became greekLetters2 and viceversa. Then, simply reload the tableview data.
-(IBAction)SwitchTable:(id)sender {
NSArray *temp = [NSArray arrayFromArray:greekLetters];
greekLetters = [NSArray arrayFromArray:greekLetters2];
greekLetters2 = [NSArray arrayFromArray:temp];
[tableview reloadData];
}
Just have one nsmutablearray which will drive your tableview. If your greekLetters array would be nsmutablearray you would update it and then reload your tableview:
[self.greekLetters addObjectsFromArray:self.greekLetters2];
[self.tableView reloadData];
Fallow these two tutorials and they will guide you in achieving what you are looking for:
- https://www.youtube.com/watch?v=gT8ncroYdDw
- https://www.youtube.com/watch?v=NHzm-D9VsQA