How to add ActivityIndicator on Custom TableviewCell's button click? - ios

I have problem with my custom tableview cell button click event with load activity indicator on selected cells button.
If you have link or other source then please help me out.
I am new in iOS development.

This is significantly easier because it doesn't involve any third party stuff (even though MBProgressHUD is a great tool). When I created the cell, I created a UIACtivityIndicatorView and added it as the cell's accessoryView. Later, when a row is pressed, I grab a reference to the cell itself at the appropriate indexPath, and then access its accessoryView property, which is the indicator view. From there you can just tell it to start animating.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
cell.accessoryView = activityIndicator;
}
cell.textLabel.text = _items[indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// deselect the row if you want the cell to fade out automatically after tapping
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// get a reference to the cell that the user tapped
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// get the tapped cell's accessory view and cast it as the activity indicator view
UIActivityIndicatorView *activityIndicator = (UIActivityIndicatorView *)cell.accessoryView;
// tell it to start animating
[activityIndicator startAnimating];
}
This results in the following after tapping the first cell:
You'll have to change the code a bit depending on when/how you want to stop the activity indicator from spinning, but without have more information from you this is the best info I can provide. You'll likely want to add the indexPath.row integer to the progressView's tag property, but there's a bit more to that. Hope this helps!
EDIT
Add a tag to the button that's the indexPath of the row, and do something like:
- (void)showProgressViewForButton:(id)sender {
NSInteger tappedCellIndex = sender.tag;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:tappedCellIndex inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UIActivityIndicatorView *activityIndicator = (UIActivityIndicatorView *)cell.accessoryView;
[activityIndicator startAnimating];
}

here is the link for MBProgressHUD:
https://github.com/jdg/MBProgressHUD

Related

Tableview Cell requires two taps to reveal the view

I had a problem with table view didSelect method and prepareForSegue. I used SWRevealController in my app. While selecting cell it reveals the view. Sometimes it not worked properly. It takes two taps to reveal the view. A few months back I used old reveal view frame which contains perform block action. Its worked perfectly.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
for (int i=0; i<6; i++)
{
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
if (i == indexPath.row)
{
cell.contentView.backgroundColor = [UIColor colorWithRed:KColorRedSelected green:KColorGreenSelected blue:KColorBlueSelected alpha:1];
}
else
{
cell.contentView.backgroundColor = [UIColor colorWithRed:KColorRed green:KColorGreen blue:KColorBlue alpha:1];
}
}
}
Add this code inside of didSelectRowAtIndexPath and didDeselectRowAtIndexPath functions
dispatch_async(dispatch_get_main_queue(), ^{
//Write code what you need
});
That works for me.
The problem is with this line
[self tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
You are calling the delegate method, which dequeues a reusable cell (I assume, since it's standard behavior). You do not want to dequeue a reusable cell, you want to do something with a cell that is currently displayed at indexPath. To do that use method from UITableView
[tableView cellForRowAtIndexPath:indexPath];
The full code
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// grab the selected cell and give it selected color
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor colorWithRed:KColorRedSelected green:KColorGreenSelected blue:KColorBlueSelected alpha:1];
}
- (void)tableView:(UITableView*)tableView didDeselectRowAtIndexPath:(NSIndexPath*)indexPath
{
// grab the deselected cell (if it's still visible) and give it deselected color
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor colorWithRed:KColorRed green:KColorGreen blue:KColorBlue alpha:1];
}
You will also need to set appropriate color in UITableViewDelegate method cellForRowAtIndexPath, since the color you once set will stay in the cell when it's reused.
This s completely wrong method to get clicked cell
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
And don't use for loop as well. instead of this you should use
UITableViewCell *cell = [tableView cellForIndexPath:indexPath];
to get correct cell.

Hide Label from prototype cell in TableView

I am working on Prototype TableView Cell where I have two Label over cell and one button behind the cell. I want to hide the second label on Hide Button click. I have tried a lot but did not get any appropriate info, Here is my code for displaying the Labels in Cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"TableCell";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
// Configure the cell...
int row = [indexPath row];
cell.EnglishLable.text = _English[row];
cell.UrduLable.text = _Urdu[row];
return cell;
}
Everything is fine, I just need to hide 'UrduLabel' in my Hide IBAction method.
- (IBAction)Hide:(id)sender {
static NSString *simpleTableIdentifier = #"TableCell";
UITableView *tableView = [[UITableView alloc]init];
CGPoint location = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:IndexPath];
BOOL *hideLabel;
hideLabel = YES;
[self.tableView reloadData];
UILabel *subtitle = (UILabel *)[cell.contentView viewWithTag:1];
subtitle.hidden = hideLabel;
}
Whats wrong in my Button method?
Try this code
- (IBAction)Hide:(id)sender {
CGPoint location = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
TableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.UrduLable.hidden = YES;
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:<any row animation you need>];
UILabel *subtitle = (UILabel *)[cell.contentView viewWithTag:1];
subtitle.hidden = hideLabel;
}
You just need to get the particular cell of which the button is clicked, hide the required label and reload the particular cell. And main thing is you need to get an instance of your prototype cell class, not of UITableViewCell
IN CASE ONE BUTTON IN THE VIEWCONTORLLER FOR ALL CELL
Incase of single button toggling the visibility of the UrduLabel, declare the -(IBAction)hide:(sender)id in the yourviewcontroller.m. connect the IBAction of the button from nib/storyboard to the -(IBAction)hide:(sender)id method.
Then follow the following steps
declare a BOOL property variable or ivar inside the view controller. named willShowUrdu.
implement the hide as following:
-(IBAction)hide:(id)sender
{
willShowUrdu = !(willShowUrdu);
[yourTableView reloadData];
}
inside the cellForRowAtIndexPath:
TableViewCell *cell = //whatever the way you get the cell
cell.UrduLabel.hidden = !willShowUrdu;
Thats how toggle the visibility of all UrduLabel under one IBAction.
IN CASE OF EACH BUTTON IN EACH CELL
There is a better way to de-centralize the control to each cell. Move the -(IBAction)hide:(sender)id method to the implementation in the TableViewCell's implementation.
Add the IBAction from nib/storyboard to the moved -(IBAction)hide:(sender)id method.
Take a IBOutlet of the UrduLabel, as seen in above code, it's already taken.
Then the implementation of -(IBAction)hide:(sender)id would be following:
-(IBAction)hide:(sender)id
{
//put your other logic here (if any)
self.UrduLabel.hidden = YES;
}
Welcome to IOS, Happy coding.

Detecting which button clicked in prototype cell in ios

I created one prototype cell. Cell has one label and one button. I have given tag's for both.
Now i want to detect which button is clicked from 10 cells.
Previously we were differentiating that based on tag. But how to do this with prototype cell.
My code for cell creation is as follows:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cellIdentifier"];
}
UIButton *stopStartButton = (UIButton *)[cell viewWithTag:103];
UILabel *chargingLabel = (UILabel *)[cell viewWithTag:102];
}
-(IBAction)stopStartButtonClicked:(id)sender
{
NSLog(#"Button clicked");
}
You can use button.titleLabel.tag for differentiate your button and at action time you can compare with same tag.
second option is with your button action. you can append event so that is also provide you all information regarding your button.
For example you just set
stopStartButton.titleLabel.tag=1;
-(IBAction)stopStartButtonClicked:(id)sender
{
NSLog(#"Button clicked %d",sender.titleLabel.tag);
}
I think the best way is to find what cell does actually has button that was tapped. You can find it by calculating x origin point of button.
- (IBAction)stopStartButtonClicked:(id)sender
{
CGPoint pointInTable = [button convertPoint:button.bounds.origin toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:pointInTable];
}
If you have indexPath, you can get cell:
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

scrollToRowAtIndexPath when Button inside UITableViewCell is pressed

I have a tableview with a few custom cells. Inside the first one is a button. When this button is pressed I want to scroll to a certain Section in my tableview. How do I have to link the button action with the tableview?
You can scroll to a certain section with using this function :
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated
the example of usage is :
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:5 inSection:indexPath.section]
atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
and for link the button action with tableview you can use protocol in you custom cell
You can make your cell's button a property and in cellForRowAtIndexPath you can set the target in the class that loads the table view so you won't need any delegates. Something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"YourCellIdentifier";
YourCustomCell *cell =[tableView dequeueReusableCellWithIdentifier:identifier];
if(cell == nil) {
cell = [YourCustomCell alloc/init method....
[cell.buttonProperty addTarget:self action:#selector(cellButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
}
//do other stuff with your cell
}
-(void)cellButtonTapped:(id)sender {
UIButton *button = (UIButton*)sender;
YourCustomCell *cell = (YourCustomCell*)button.superview.superview; //if the button is added to cell contentView or button.superview is added directly to the cell
NSIndexPath *path = [yourTableView indexPathForCell:cell];
[yourTableView scrollToRowAtIndexPath:path
atScrollPosition:UITableViewScrollPositionTop
animated:YES];
}
Set up a delegation mechanism back from your cell - when creating the cell, assign it an NSIndexPath and pass it back from the cell when the button is tapped.
So in your UITableViewCell subclass you'll have:
- (IBAction)buttonPressed:(id)sender
{
[self.delegate buttonPressedOnCellAtIndexPath:cell.indexPath]
}
Back in the controller that's the delegate, respond to this method with:
- (void)buttonPressedOnCellAtIndexPath:(NSIndexPath)indexPath
{
[self.tableView scrollToRowAtIndexPath:indexPath];
}

Programmatically highlight UITableView cell

I have an iPad app which uses a UISplitViewController (with a UITableView on the left and a detail view on the right). My table view highlights the selected cell in blue when you tap on it.
When I call the following method, the cell is selected but not highlighted in blue:
[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionTop];
I have spent literally days fiddling about with various delegate methods and hacks trying to get the cell to highlight programatically just as if it had been tapped. I can't do it.
I've managed to almost get there with this:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (shouldHighlightCell)
{
NSIndexPath *indexPathForCellToHighlight = [NSIndexPath indexPathForRow:0 inSection:0];
if ([indexPath isEqual:indexPathForCellToHighlight])
{
cell.selected = YES;
shouldHighlightCell = NO;
}
}
}
It works as long as I also have this (otherwise it remains selected even when another cell is tapped):
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *ip = [NSIndexPath indexPathForRow:0 inSection:0];
if ([[self.tableView cellForRowAtIndexPath:ip] isSelected])
{
[[self.tableView cellForRowAtIndexPath:ip] setSelected:NO];
}
NSIndexPath *iToTheP = indexPath;
return iToTheP;
}
I know this is a weird and convoluted workaround. I wouldn't mind, but it doesn't even work fully. The selected cell loses its highlight if it is scrolled off screen, whereas a cell that has been tapped remains highlighted when scrolled off screen.
I'm absolutely baffled by this. I'm sure this workaround shouldn't even be necessary, that there is a much simpler solution.
Please be sure the cell's selectionStyle is UITableViewCellSelectionStyleBlue and the tableView's allowsSelection is set to YES.
The method selectRowAtIndexPath:animated:scrollPosition: works fine for me. It does highlight the selected cell.
I went through and tried all these and other solutions and no joy. In my case the problem (which drove me nuts for 2 hrs) was the following - shortly after I was calling selectRowAtIndexPath, I was calling reloadData on the tableview. That reload was wiping all the highlighting! Beware of this pitfall! With the unnecessary reloading of data call gone, the highlighting happenned as expected.
I also tried many approaches to get the initial selection to display on my single-selection UITableView. What finally worked for me was to defer the selection of the initial row until the table was set up by calling it in my UITableViewController's viewDidAppear:
override func viewDidAppear(animated: Bool)
{
tableView.selectRowAtIndexPath(indexPathToSelectInitially, animated: false, scrollPosition: .None)
}
I found this and it works for me (aka calling the delegate method didSelectRowAtIndexPath)
NSIndexPath *defaultIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self tableView:[self tableView] didSelectRowAtIndexPath:defaultIndexPath];
PS. I'm using UITableViewController.
I found this to be completely unfixable using all known possibilities. In the end I fixed it by ditching a lot of my code and switching to NSFetchedResultsController instead. NSFetchedResultsController was introduced shortly after I originally wrote this app, and it greatly simplifies the process of using Core Data with UITableViews.
https://developer.apple.com/library/IOs/documentation/CoreData/Reference/NSFetchedResultsController_Class/index.html
It gets the backgroundview with cell border looking like seperator.Do not change the default tableview settings in Interface builder.Make sure UITableViewCellSelectionStyleNone is NOT set to selectionstyle. I am pasting the working code. :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *kCellIdentifier = #"PlayListCell";
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellIdentifier];
}
MPMediaPlaylist *playList = [playlistCollection objectAtIndex:indexPath.row];
cell.textLabel.text = playList.name;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%d Songs",[playList.items count]];
MPMediaItemCollection *playListMediaCollection = [playlistCollection objectAtIndex:indexPath.row ];
cell.imageView.image =[UIImage imageWithCGImage:[self getImageForCollection:playListMediaCollection.items]];
// the main code which make it highlight
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor colorWithRed:170.0f/255.0 green:170.0f/255.0 blue:170.0f/255.0 alpha:1.0f];
[bgColorView.layer setBorderColor:[UIColor blackColor].CGColor];
[bgColorView.layer setBorderWidth:1.0f];
[cell setSelectedBackgroundView:bgColorView];
return cell;
}

Resources