UITableViewCellAccessoryDetailDisclosureButton disappearing after changing UITableViewCell accessory - iphone

I have a UITableView that has cells with images, text and a disclosure button. I'm loading the cells like this:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
if ([indexPath row] == [[self multas] count]) {
[[cell textLabel] setText:#"Carregar mais..."];
}
else
{
Multa *multa = [self.multas objectAtIndex:indexPath.row];
NSString *dataIsolada = [[NSString stringWithFormat:[multa dataOcorrencia]] substringWithRange:NSMakeRange(0, 10)];
[[cell textLabel] setText:[NSString stringWithFormat:dataIsolada]];
[[cell detailTextLabel] setText:[multa descricao]];
[cell.imageView setImageWithURL:[NSURL URLWithString:[multa fotoURL]]
placeholderImage:[UIImage imageNamed:#"carregando.jpeg"]];
[cell.imageView setContentMode: UIViewContentModeScaleAspectFit];
[cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
}
return cell;
}
When the user taps the disclosure button, I switch the disclosure button for an Activity Indicator and then push another view to the screen using a navigation controller:
- (void)carregarDetalhesMulta:(UITableView *)tableView comMulta:(Multa *)multa
{
DetalheMultaViewController *form = [[DetalheMultaViewController alloc] initWithMulta:multa];
form.delegate = self;
UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:form];
[self presentModalViewController:navigation animated:YES];
}
- (void) tableView: (UITableView *) tableView accessoryButtonTappedForRowWithIndexPath: (NSIndexPath *) indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray];
spinner.frame = CGRectMake(0, 0, 24, 24);
cell.accessoryView = spinner;
[spinner startAnimating];
Multa *multa = [self.multas objectAtIndex:indexPath.row];
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[spinner stopAnimating];
[self carregarDetalhesMulta:tableView comMulta:multa];
[cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
});
}
Note that I've changed back the accessory for a disclosure button in the end. The problem is: when I come back(by tapping the button back) to the view that contains the UITableView, the line that I've tapped show no disclosure button nor Activity Indicator. What I am doing wrong? What's the better way to switch these controls without having to reload the table view?

The accessoryView property has priority over the accessoryType property. If you set the accessoryView to nil, you'll see the accessory button again.

Here's what I understood from the question: You'd like the accessory view to be a disclosure button that when tapped, becomes an activity indicator. After a short delay, you'd like to push to a new view controller.
Here's how I would do it:
setup the prototype cell in storyboard to have Accessory:none.
add a push segue from your view controller to the destination vc you want, give it an identifier, say #"MyPushSegue"
Add the accessoryView to cells (if they don't have one) in cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
// the rest of your cellForRowAtIndexPath
if (!cell.accessoryView)
cell.accessoryView = [self createAccessoryView];
return cell;
}
Create the accessory view this way (assuming ARC):
- (UIView *)createAccessoryView {
UIView *accessoryView = [[UIView alloc] initWithFrame:CGRectZero];
UIButton *disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
disclosureButton.tag = 100;
[disclosureButton addTarget:self action:#selector(pressedAccessory:) forControlEvents:UIControlEventTouchUpInside];
UIActivityIndicatorView *aiv = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
aiv.tag = 101;
aiv.alpha = 0.0;
aiv.center = disclosureButton.center;
accessoryView.bounds = disclosureButton.bounds;
[accessoryView addSubview:aiv];
[accessoryView addSubview:disclosureButton];
return accessoryView;
}
The disclosure button in the above triggers a method when the button is pressed. This method should change the state of the selector view and trigger the push segue you setup in storyboard:
- (void)pressedAccessory:(UIButton *)sender {
UIView *accessoryView = sender.superview;
[self setAccessoryView:accessoryView waiting:YES];
// let the user see the spinner for 1 seconds
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[self performSegueWithIdentifier:#"MyPushSegue" sender:self];
[self setAccessoryView:accessoryView waiting:NO];
});
}
Finally, to solve the problem you were having, we don't replace the accessory view with a spinner, we change how it looks by hiding/showing the button and hiding/showing the spinner, depending on what state we want:
- (void)setAccessoryView:(UIView *)accessoryView waiting:(BOOL)waiting {
UIButton *disclosureButton = (UIButton *)[accessoryView viewWithTag:100];
UIActivityIndicatorView *aiv = (UIActivityIndicatorView *)[accessoryView viewWithTag:101];
[UIView animateWithDuration:0.1 animations:^{
disclosureButton.alpha = (waiting)? 0.0 : 1.0;
aiv.alpha = (waiting)? 1.0 : 0.0;
}];
if (waiting) [aiv startAnimating]; else [aiv stopAnimating];
}

Related

UITableView indexPath.row value error for button action

I have a UITableView. There is a button in the right side on each row. Now the problem is any button i tap, it returns me the value of indexPath.row is 0. But when i tap a button it should return me the corresponding value of indexPath.row. I am working in iOS 7. Where is the mistake i am doing?
Here is the code for creating buttons on cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger index = [indexPath row];
UISegmentedControl *renameButton = nil;
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
renameButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Rename"]];
[renameButton setTag:6];
[renameButton addTarget:self action:#selector(renameButtonClicked:) forControlEvents:UIControlEventValueChanged];
[renameButton setSegmentedControlStyle:UISegmentedControlStyleBar];
[renameButton setMomentary:YES];
[renameButton setTintColor:[UIColor lightGrayColor]];
[cell.contentView addSubview:renameButton];
[renameButton release];
return cell;
Here is the code for the selector method:
- (void)renameButtonClicked:(id)sender {
isInEditMode = !isInEditMode;
[self setToolbarUserInterface];
[self setTableViewUserInterface];
while ([selectedItems count] > 0) {
[selectedItems removeLastObject];
}
UIButton *button = (UIButton *)sender;
UITableViewCell *cell = (UITableViewCell *)[[button superview] superview];
int index = [[self.tableView indexPathForCell:cell] row];
NSLog(#"Index value : %d",index);
NSString *newPath = [path stringByAppendingPathComponent:[items objectAtIndex:index]];
TextInputViewController *textInput = [[TextInputViewController alloc] init];
[textInput setPath:newPath Parent:parent andType:5];
[self.navigationController pushViewController:textInput animated:YES];
}
You don't get UITableViewCell by calling:
UITableViewCell *cell = (UITableViewCell *)[[button superview] superview];
Try add one more superview to access the cell:
UITableViewCell *cell = (UITableViewCell *)[[[button superview] superview] superview];
The structure the button layout on the table view is:
UITableViewCellContentView - [sender superview]
UITableViewCellScrollView - [[sender superview] superview]
UITableViewCell - [[[sender superview] superview] superview]
Hope this help
Use associated objects. This should work:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger index = [indexPath row];
UISegmentedControl *renameButton = nil;
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
renameButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Rename"]];
[renameButton setTag:6];
[renameButton addTarget:self action:#selector(renameButtonClicked:) forControlEvents:UIControlEventValueChanged];
[renameButton setSegmentedControlStyle:UISegmentedControlStyleBar];
[renameButton setMomentary:YES];
[renameButton setTintColor:[UIColor lightGrayColor]];
[cell.contentView addSubview:renameButton];
objc_setAssociatedObject(renameButton, "cell", cell, OBJC_ASSOCIATION_ASSIGN);
[renameButton release];
return cell;
Selector method:
- (void)renameButtonClicked:(id)sender {
isInEditMode = !isInEditMode;
[self setToolbarUserInterface];
[self setTableViewUserInterface];
while ([selectedItems count] > 0) {
[selectedItems removeLastObject];
}
UITableViewCell *cell = objc_getAssociatedObject(sender, "cell");
int index = [[self.tableView indexPathForCell:cell] row];
NSLog(#"Index value : %d",index);
NSString *newPath = [path stringByAppendingPathComponent:[items objectAtIndex:index]];
TextInputViewController *textInput = [[TextInputViewController alloc] init];
[textInput setPath:newPath Parent:parent andType:5];
[self.navigationController pushViewController:textInput animated:YES];
}
And don't forget to import runtime.h
#import <objc/runtime.h>
My approach would be this :
Create a custom button class which inherits a class depending on ui element you're using which triggers an action, in your case it's UISegmentedControl.
Then add a property to hold a reference to its index path.
While you are creating your UISegmentedControl set its index path.
In your action method, you can get simply its index path.
I think it's more convenient way to do what you want to do, because let's say, you want to change the view hierarchy of your cell. It's a good chance to your code needs to be changed. Also, get third superview of a UIKit element is never a good idea.
The clear way of getting the indexpath in this case would be:
NSIndexPath *index = [myTableView indexPathForCell:(UITableViewCell *)[[sender superview]superview]];

Problems Making a TableView Fade

Using UIView animateWithDuration, I'm setting a UITableView alpha to 0 so that it fades away in a disappearing animation. However, I'm noticing that when the UITableView fades, there are areas on each cell that turn black before fading. If there is an image, the whole area behind it turns black while fading, and usually the inset space on both the left and right edge turn black. I've tried setting all of the background colors of the UITableViewCell subviews to white and it still doesn't work.
This tableview is not embedded in a UITableViewController. Instead, it's a separate floating tableView that I'm using as a menu.
Here is an example of what happens when it's fading:
Here is the code I'm using as well
[UIView animateWithDuration:ImageViewControllerBarsAnimationDuration delay:0 options: UIViewAnimationOptionAllowUserInteraction animations:^
{
if (self.menu.superview)
{
self.menu.alpha = 0;
}
}
completion:^(BOOL finished)
{
if (self.menu.superview)
{
[self.menu removeFromSuperview];
self.menu.alpha = 1;
}
}];
+
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (tableViewCell == nil)
{
tableViewCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
}
[[tableViewCell textLabel] setFont:[UIFont fontWithName: #"Helvetica-Bold" size: 17]];
[[tableViewCell textLabel] setText: [self.menuItems objectAtIndex:0]];
[[tableViewCell imageView] setImage: [self.menuItems objectAtIndex:1]];
return tableViewCell;
}
DTS gave me a solution to this, have to do the following:
self.myTableView.backgroundView = nil;
self.myTableView.backgroundColor = [UIColor clearColor];
Then inside of cellForRowAtIndexPath method have to do this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kOneCellID = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kOneCellID];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kOneCellID] autorelease];
cell.backgroundView = [[UIView alloc] init];
cell.backgroundView.backgroundColor = [UIColor whiteColor];
}
...
}
What is self.menu? If you put tableView in its place it works exactly fine.
[UIView animateWithDuration:ImageViewControllerBarsAnimationDuration delay:0 options: UIViewAnimationOptionAllowUserInteraction animations:^
{
if (tableView.superview)
{
tableView.alpha = 0;
}
}
completion:^(BOOL finished)
{
if (tableView.superview)
{
[tableView removeFromSuperview];
tableView.alpha = 1;
}
}];

passing the toggle button value to switch button state in another class in iphone

i have an application in which i have 2 tableview controller.In first tableview, i have a button created in my cellforRowAtIndexPath of my first tableview. Initially i have set the button image to 'ON' image which means my alarm is on .Then when i click on the edit button my tableview changes to editmode where i can change my button image to 'OFF'.i want that my button action should be called when the tableview enters in edit mode.This is the code that i have written.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d%d", indexPath.section, indexPath.row];
appDelegate = (StopSnoozeAppDelegate*)[[UIApplication sharedApplication]delegate];
TAlarmCell *cell =(TAlarmCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[TAlarmCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
mimageButton = [UIButton buttonWithType:UIButtonTypeCustom];
mimageButton.frame=CGRectMake(10, 20, 20, 20);
mimageButton.tag = 1;
[mimageButton setImage:[UIImage imageNamed:#"alarm_ON.png"] forState:UIControlStateNormal];
[mimageButton setImage:[UIImage imageNamed:#"alarm_OF.png"] forState:UIControlStateSelected];
[cell.contentView addSubview:mimageButton];
}
cell.editingAccessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
//this is my edit code.
-(void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[mTableView setEditing:editing animated:YES];
if (editing)
{
[mimageButton addTarget:self action:#selector(changeMapType:) forControlEvents: UIControlEventTouchUpInside];
self.navigationItem.rightBarButtonItem = nil;
}
else {
self.navigationItem.rightBarButtonItem = addButton;
[self.mTableView reloadData];
}
}
//this is my button action
-(void)changeMapType:(UIButton *)sender
{
NSIndexPath *indexPath =[self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
NSUInteger row = indexPath.row;
NSLog(#"row...%d",row);
appDelegate.changeimagetype = !appDelegate.changeimagetype;
sender.selected = appDelegate.changeimagetype;
[self.tableView reloadData];
}
But the problem here is when i click on edit button and tableview enters in edit mode,changeMapType: action is not getting called and my image does not changes.
can u give me some details about
where u r setting this flag
if (editing)
and for which action of user u want this method to get to called..?
-(void)changeMapType:(UIButton *)sender
if u want to get called immediately after entering into edit mode, u can use the below method
[self performSelector:#selector(changeMapType:)];

Adding a UITextField to a UITableViewCell only shows a textField in the LAST cell

I have a table view that has many cells. Each cell has its own UITextField. I added the text fields programmatically. I want each and every textField to appear when the edit button is hit. (now table is in edit mode) and when pressed again, i want all of the textFields to vanish(leaving the edit mode). I know that i can accomplish this using the hidden property, but i tried doing this in this method:
- (IBAction)editButton:(id)sender
{
if (self.editing)
{
[self setEditing:NO animated:YES];
[self.myTableView setEditing:NO animated:YES];
EditButton.title = #"Edit";
cellText.hidden = YES; //<-- THIS IS THE CODE
}
else
{
[self setEditing:YES animated:YES];
[self.myTableView setEditing:YES animated:YES];
EditButton.title = #"Done";
cellText.hidden = NO; //<-- THIS IS THE CODE
}
}
but it only shows and hides the VERY LAST cell's textField. How can i get it to where it shows and then doesnt show EVERY cell's textFIeld? Many thanks in advance!!!
CELL FOR ROW
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cellText = [[UITextField alloc]init];
[cellText setFrame:CGRectMake(190, 15, 55, 30)];
cellText.text = #"1";
cellText.borderStyle = UITextBorderStyleRoundedRect;
cellText.hidden = YES;
cellText.userInteractionEnabled = NO;
[cell addSubview:cellText];
}
return cell;
}
Thanks in advance!! :D
You can get rid of this issue, using this trick, I am not sure as if it would create the memory leak within your code.Since, it create new cell each time.But surely you can use it,if you don't get some proper way of doing it. ;)
- (IBAction)editButton:(id)sender
{
if (self.editing)
{
[self setEditing:NO animated:YES];
[self.myTableView setEditing:NO animated:YES];
EditButton.title = #"Edit";
}
else
{
[self setEditing:YES animated:YES];
[self.myTableView setEditing:YES animated:YES];
EditButton.title = #"Done";
}
[self.myTableView reloadData];
}
After reloading the TableView, check the condition in cellForRowAtIndexPath, either pass the value of self.editing to TextField which makes it hide/show.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cellText = [[UITextField alloc]init];
[cellText setFrame:CGRectMake(190, 15, 55, 30)];
cellText.text = #"1";
cellText.borderStyle = UITextBorderStyleRoundedRect;
cellText.hidden = YES;
cellText.backgroundColor = [UIColor redColor];
cellText.userInteractionEnabled = NO;
[cell addSubview:cellText];
cellText.hidden=!self.editing;
return cell;
}
Although you create a text field for each cell, you keep a reference only to the last one in the ivar named cellText. That's why you show/hide the only text field.
I suggest you reload the table when toggling the editing mode, and set the text fields visibility in tableView:cellForRowAtIndexPath:.
Oh, and you should release cellText after adding it as a subview. Otherwise you are leaking memory. And it is highly recommended that you add subviews to UITableViewCell content view, rather than directly to the cell.
Try this code
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (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] autorelease];
}
UITextField * cellText = [[UITextField alloc] initWithFrame:CGRectMake(1, 1, 100, 30)];
cellText.tag = 1;
cellText.textColor = [UIColor darkTextColor];
//cellText.numberOfLines = 0;
cellText.font = [ UIFont fontWithName: #"Helvetica-Bold" size: 12.0 ] ;
cellText.backgroundColor = [ UIColor clearColor ] ;
cellText.text = #"123";
cellText.hidden = YES;
[cell.contentView addSubview:cellText];
[cellText release];
cellText =nil;
// Set up the cell...
return cell;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
// Detemine if it's in editing mode
UITextField *cellText = (UITextField *)[[aTableView cellForRowAtIndexPath:indexPath] viewWithTag:1];
if (!self.editing)
{
[self setEditing:NO animated:YES];
[self.tableView setEditing:NO animated:YES];
// EditButton.title = #"Edit";
cellText.hidden = YES; //<-- THIS IS THE CODE
}
else
{
[self setEditing:YES animated:YES];
[self.tableView setEditing:YES animated:YES];
// EditButton.title = #"Done";
cellText.hidden = NO; //<-- THIS IS THE CODE
}
return UITableViewCellEditingStyleNone;
}
hi friend this code is working fine for me, believe you too have a grate day
This is actually normal. Per the Apple documentation under addSubview:
Views can have only one superview. If view already has a superview and
that view is not the receiver, this method removes the previous
superview before making the receiver its new superview.
So it will keep removing it adding and removing from cells until it gets to the last one.

How to set an UIActivityIndicatorView when loading a UITableViewCell

I have two UITableViewControllers, A and B. When I tap one cell in table A, I will use UINavigationController to push table view controller B. But the data of B is downloaded from Internet, which takes several seconds. So I want to add a UIActivityIndicatorView when loading B. How can I achieve this?
You can add UIActivityIndicatorView as cell's accessoryView.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.frame = CGRectMake(0, 0, 24, 24);
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryView = spinner;
[spinner startAnimating];
[spinner release];
}
In viewDidLoad of tableview B class, add an activity indicator.
// Create the Activity Indicator.
let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
activityIndicator.hidesWhenStopped = true
view.addSubview(activityIndicator)
// Position it at the center of the ViewController.
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor),
activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor)])
activityIndicator.startAnimating()
Now call your method that downloads data from the network.
myDownloadMethod()
Do it in a different thread if you don't want the UI to be non responsive during the process.
read this thread for that.
Can I use a background thread to parse data?
When you are notified that the contents are downloaded, stop the indicator.
activityIndicator.stopAnimating()
Now you can call tableview.reloadData() for reloading the table to display the new contents.
UIActivityIndicatorView * activityindicator1 = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(150, 200, 30, 30)];
[activityindicator1 setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
[activityindicator1 setColor:[UIColor orangeColor]];
[self.view addSubview:activityindicator1];
[activityindicator1 startAnimating];
[self performSelector:#selector(callfunction) withObject:activityindicator1 afterDelay:1.0];
-(void)callfunction
{
// Here your stuf
}
It's work well for me, you can try it:
Call [activityIndicator startAnimating] when didHighlightRowAtIndexPath,
and call [activityIndicator stopAnimating] when didUnhighlightRowAtIndexPath useful than didSelectRowAtIndexPath.
- (void)runIndicatorAtIndexPath:(NSIndexPath *)indexPath display:(BOOL)playing{
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.accessoryView = activityIndicator;
playing == YES ?[activityIndicator startAnimating]:[activityIndicator stopAnimating];
}
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
[self runIndicatorAtIndexPath:indexPath display:YES];
}
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath{
[self runIndicatorAtIndexPath:indexPath display:NO];
}
This code below will display a spinner at the footer of the table view if more data is available on the server. You can change it according to your logic of fetching data from server.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
/* set cell attributes here */
NSInteger lastSectionIndex = [tableView numberOfSections] - 1;
NSInteger lastRowIndex = [tableView numberOfRowsInSection:lastSectionIndex] - 1;
if ((indexPath.section == lastSectionIndex) && (indexPath.row == lastRowIndex)) {
if(isMoreDataAvailableOnserver)
{
[self showSpinnerAtFooter];
[self getMoreDataFromServer];
}
else {
[self hideSpinnerAtFooter];
}
}
return cell;
}
- (void)hideSpinnerAtFooter {
self.tableView.tableFooterView = nil;
}
- (void)showSpinnerAtFooter {
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
spinner.frame = CGRectMake(0, 0, 320, 44);
self.tableView.tableFooterView = spinner;
}