When I click on table cell, there's a short delay of 1-2 second before it loads the next view. I've seen some apps that show an activity indicator during that time and that's what I'd like to do. I've added one like this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
spinner.frame = CGRectMake(200,200,200,200);
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryView = spinner;
[spinner startAnimating];
[spinner release];
VenueViewController *vviewcontroller = [[VenueViewController alloc] initWithNibName:#"VenueViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:vviewcontroller animated:YES];
[vviewcontroller release];
vviewcontroller = nil;}
however this also appears with a delay, and just before the next view is showing. It seems the app freezes for 1-2 seconds after clicking on the table cell so it doesn't even show the activity indicator.
I think the secret is that you should call load method using a performSelector method. Another tip is hiding or showing the activity so it won't consume time this operation.
So this could be a pseudocode of that
Inside your ViewController class definition:
IBOutlet UIActivityIndicatorView *spin; // created in view and hidden
In your implementation...
-(void) load{ // your code
VenueViewController *vviewcontroller = [[VenueViewController alloc] initWithNibName:#"VenueViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:vviewcontroller animated:YES];
[vviewcontroller release];
vviewcontroller = nil;
spin.hidden=YES;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
spinner.hidden=NO;
[self performSelector:#selector(load) withObject:nil afterDelay:0];
}
Hope it helps.
Related
Ever since the new iOS 11 update, I have an app that will show blank tableview rows on the simulator and device. Even the row separators will not show for any of the rows that are supposed to be there. If I change the simulator to an older iOS version, the rows will show fine. No changes to code or storyboard.
The rows still have the data, meaning I can tap on one of the blank rows and it will execute the code and contain the information I was expecting.
It appears that other scenes that I have where the tableview is placed on a view and I don't use the built in text label work fine. Just this tableview class using the built in text label.
Here is my code for the tableview class...
#interface BunkPickTableViewController ()
#end
#implementation BunkPickTableViewController
#synthesize appDelegate, delegate, bunkPassedValue;
- (void)viewDidLoad {
[super viewDidLoad];
UIView *backgroundView = [[UIView alloc] initWithFrame:self.view.bounds];
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
CAGradientLayer *bgLayer = [BackgroundLayer tanGradient];
bgLayer.frame = self.view.bounds;
[self.view.layer insertSublayer:bgLayer atIndex:0];
self.tableView.backgroundView = backgroundView;
[self.navigationController.navigationBar setTintColor:[UIColor blackColor]];
self.title = #"Bunk Codes";
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[self navigationController] setNavigationBarHidden:NO animated:NO];
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [appDelegate.bunkArray count];
}
- (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];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.backgroundColor = [UIColor clearColor];
}
Bunk *bunkObj = [appDelegate.bunkArray objectAtIndex:indexPath.row];
cell.textLabel.text = bunkObj.bunkId;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
Bunk *bunkObj = [appDelegate.bunkArray objectAtIndex:indexPath.row];
[delegate dismissBunkPop:bunkObj.bunkId];
[self.navigationController popViewControllerAnimated:YES];
}
#end
TableView Settings Image
I had this issue as well with IOS 11 showing blank cells.. but in IOS 10 was fine. My issue was that I was using a gradient which for whatever reason stopped the cell text from being shown. Removing the gradient resolved the blank cells.
This is probably because your tableView gets under bgLayer.
The problem seems to be in self.view.layer insertSublayer:bgLayer atIndex:0. I was using insertSubview at index 0 and I had the same problem. This is probably a bug in iOS 11 - if your tableView is defined in storyboard, it always gets pushed to back.
The best solution is to put the bgLayer inside the tableView.backgroundView.
NOTE:
You could also solve it by calling sendSubviewToBack on the bgLayer in viewDidAppear, but unfortunetaly, tableview cells are moving to back on every tableview reloaddata, so it is not a good solution.
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.tableView.bounds;
gradient.colors = #[(id)[UIColor blackColor].CGColor, (id)[UIColor
grayColor].CGColor, (id)[UIColor
lightGrayColor].CGColor];
UIView *bgView = [[UIView alloc]
initWithFrame:self.tableView.bounds];
[self setBackgroundView:bgView];
[bgView.layer insertSublayer:gradient atIndex:0];
[self.tableView setBackgroundView:bgView];
Setting gradient layer for tableview's background view solved the problem for me. Upto iOS 10 we can directly insert sublayer to tableView but in iOS 11 layer should be inserted to UITableVIew's background view only.
In tandem with the aforementioned tableview subviews manipulation, this problem can also occur if your project existed pre Xcode 9 and you then checked Use Safe Area Layout Guides on your storyboard. Try unchecking that and see if it works.
So i have set a plist and everytime someone click on the cell in table view i want it to load in the detail view. The only problem is that when it is clicked it loads a dark black screen with nothing on it. Any suggestions?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Index Selected,%d",indexPath.row);
WebViewController *modalView = [[WebViewController alloc] init];
NSString *urltoPass = [NSString stringWithString:[[tableData objectAtIndex:indexPath.row]objectForKey:#"cellSubtitle"]];
modalView.urlString = [[NSString alloc] initWithFormat:#"http://%#",urltoPass];
modalView.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:modalView animated:YES completion:nil];
}
You forgot to actually present the new view controller. You have to add the following line to the bottom of your didSelectRowAtIndexPath: method.
[self presentViewController:modalView animated:YES completion:nil];
Also, you can remove the line below entirely as it doesn't do anything in its current form.
[self.navigationController modalTransitionStyle];
I've got a tableview containing array of names. The search bar works perfectly filtering the names in the table view.
The problem is the didSelectRowAtIndexpath is not getting fired when clicking the search tableview cell. Could you help me out?
What is the thing that I'm missing? Should I include any special delegate to involve search tableview cell click.
Below is the image and code.
-(void)search
{
nameArray = [[NSMutableArray alloc] init];
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 160, 44)];
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
self.tableViewFriendsList.tableHeaderView = searchBar;
}
- (void)searchDisplayController:(UISearchDisplayController *)controller
willShowSearchResultsTableView:(UITableView *)tableView
{
[tableView setRowHeight:70];
[tableView reloadData];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.tableViewFriendsList) {
NSString *friendsID =[[[self.friendsDictionary objectForKey:#"data"] objectAtIndex:indexPath.row] objectForKey:#"id"];
[[FacebookHelper sharedFacebookHelper] postOnWallWithDelegate:self andID:friendsID];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
NSLog(#"I ve come here");
NSString *friendsID =[friendsListIdArray objectAtIndex:indexPath.row];
[[FacebookHelper sharedFacebookHelper] postOnWallWithDelegate:self andID:friendsID];
}
}
You forgot to set
searchController.searchResultsDelegate = self;
I do something in one of my projects that may be of assistance:
// add gesture to detect when table view is being tapped so that keyboard may be dismissed
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(dismissKeyboard)];
gestureRecognizer.cancelsTouchesInView = NO;
[self.tableView addGestureRecognizer:gestureRecognizer];
Moreover I am wondering why you have a search bar within a table cell. Would you mind posting a screen shot of it in your app? I am afraid you may be doing more work than is necessary.
Quick question on popovers, i seem not grasp a way of closing a popview when i select something from it (tableview)
so i have a list items on a tableview which popup using a UIPopoverController so when i select an item i'd like to the popove to fade away.
MainViewController
- (IBAction)popoverFontName:(id)sender
CGRect popoverRect = [self.view convertRect:[popoverFontName frame]
fromView:[popoverFontName superview]];
TitleController *titleC=[[TitleController alloc]init];
popup =[[UIPopoverController alloc]initWithContentViewController:titleC];
[popup presentPopoverFromRect:popoverRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[popup setPopoverContentSize:CGSizeMake(50.0, 300.0)];
[titleC release];
}
TitleController
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selectedLang = [titleList objectAtIndex:indexPath.row];
//Initialize the detail view controller and display it.
MyDetViewCont *myDetViewCont = [[MyDetViewCont alloc] initWithNibName:#"myDetViewCont" bundle:[NSBundle mainBundle]]; // view controller instance
}
On the title contoller i dont know how to dismiss the popover
You can call dismissPopoverAnimated: on the popoverController. You should keep an instance of your popover as an instance variable in order to dismiss from the UITableViewDelegate methods.
While trying out an experimental UINavigationController-based iPhone application, I ran into a problem when the user navigates back to the previous view.
The simple application uses a UINavigationController, onto which new instances of UIViewControllers are pushed.
These instances are all of the same class (in this example, class MyViewController a sub-class of UIViewController), and are manually created (not using a NIB). Each instance contains a separate UITableView instance as the UIViewController's view.
The following tableView:didSelectRowAtIndexPath: method is from the MyViewController class. It creates and pushes another MyViewController instance onto the navigationController when the user selects a table cell:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MyViewController *nextViewController = [[MyViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:nextViewController animated:YES];
[nextViewController release];
}
The user can navigate forwards through a sequence of views, each one containing a table. The problem occurs when navigating back to the previous screen. The application aborts and xcode starts the debugger.
The error can be prevented by not releasing the MyViewController instance in the tableView:didSelectRowAtIndexPath: method above, or by not calling dealloc on the 'myTableView' instance in MyViewController's dealloc method.
However, that's not a real solution. As far as I know, the UINavigationController "owns" the pushed UIViewController instance, which can then safely be released from the client that allocated it. So, what can be wrong with this experimental app? Why would it terminate when the user navigates back?
Below are a few other methods of the MyViewController class:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
self.title = #"My Table";
myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
myTableView.delegate = self;
myTableView.dataSource = self;
self.view = myTableView;
}
return self;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyTable"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0,0, 300, 50) reuseIdentifier:#"MyTable"];
[cell autorelease];
}
cell.text = [NSString stringWithFormat:#"Sample: %d", indexPath.row];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3; // always show three sample cells in table
}
- (void)dealloc {
[myTableView dealloc];
[super dealloc];
}
EDIT:
Problem fixed - thanks Rob Napier for pointing out the problem.
The -loadView method now sets up the view using a local UITableView instance:
- (void)loadView {
UITableView *myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
myTableView.delegate = self;
myTableView.dataSource = self;
self.view = myTableView;
[myTableView release];
}
You're setting the view in the wrong method. You should set this up in -loadView, not -initwithNibName:bundle:. Look in View Controller Programming Guide "Using View Controllers" for an example.