How to refresh individual UITableViewCells? - ios

I'm having UITableView with few UITableViewCells,
Which plays Different Audio files based on their index path.
I'm showing play/pause button in UITableViewCell.
on play button click in a UITableViewCell,i wanted to reset play button state for last played cell to default(Play).
Storing index of cell in which the play button tapped would do the thing,but we need to reload all the UITableView,Instead of reloading entire UITableView,can't we refresh/reload individual UITableViewCells?
Any help will be appreciated,
Thanks in-advance.

Two step:
1.find get the press row by rewrite your UITableCellView's button's action method
2.update the press row's image

Abstract tip: When using table views have every case implemented in its cellForRow method, that is in its data source. After any change of state or actual data just reload the table with reloadData.
Work for me every time.
More detailed: In your case - have a global index var to show which row is 'playing' now. In cellForRow check if current and global indexes match and show the right button.
Note, that you can also assign tag to any view (buttons also), this can be useful to know which row each button belongs to.

if you have IndexPath of selected cell; then you can get the cell by
UITableViewCell *cell = [UITableviewObj cellForRowAtIndexPath:selIndexPath];
now you have reference to cell; you can change cells content. i would suggest not to change height of the cell through this process.

If I understand correctly, when a user taps a Play button in a different cell, you want to pause the one currently playing and play the new one. The previous cell image should go back from Pause to Play.
In your code where you change Play to Pause and start playing, save an Index path of that cell. Next time Play is clicked check if you have an Index path saved, get the cell and reset the image on it. Something like this:
tableView:didSelectCell {
if (lastPlayingCellPath) {
MyCell *cell = [tableView cellForRowAtIndexPath:lastPlayingCellPath];
[cell setPlayImage];
}
// Play Audio and change current cell image to Pause
lastPlayingCellPath= selectedCellPath;
}
The above is pseudo code, but you should get the idea.
EDIT: From the comments I figured that your custom UITableViewCell subclass handles the tap event. You could fire a notification that you are starting to play. Every cell would subscribe to that event and reset the state of it's button. So you could do something like this in your subclass
- (instancetype)init {
// standard init code
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willPlay) name:#"CellWillPlayNotification" object:nil];
}
- (void)willPlay {
[self setPlayImage];
}
-(void)buttonTapped {
[[NSNotificationCenter defaultCenter] postNotificationName:#"CellWillPlayNotification" object:self];
// Do your standard handling of the tap
}

Related

Need to disable particular button in swipe cell?

I am using https://github.com/CEWendel/SWTableViewCell library to my project.
Certain situation I need to disable the particular button action of swipe cell.
I cannot find any property in their class file. If anyone crossed this, give me answer.
Here I have attaced my swipe options image:
For ex
: I want to disable the share button action.
Let's assume your share button is in the leftButtonsArray. In the method:
- (void)swipeableTableViewCell:(SWTableViewCell *)cell scrollingToState:(SWCellState)state
{
//case:left buttons opened
UIButton *shareButton = leftButtonsArray[theIndexOfTheShareButton];
shareButton.enabled = NO;
}
#karthikeyan You can hide the button for a particular row in tableview by the following code:
- (void)updateRightUtilityButtons:(NSArray *)rightUtilityButtons WithButtonWidth:(CGFloat) width {
_rightUtilityButtons = rightUtilityButtons;
[self.rightUtilityButtonsView updateUtilityButtons:rightUtilityButtons WithButtonWidth:width];
[self.rightUtilityButtonsView layoutIfNeeded];
[self layoutIfNeeded];
}
Add/update this methods to SWTableViewCell.m class, where rightUtilityButtons is an array of buttons you need to display for the particular row.
In case if you want to disable just user interaction you can achieve while adding button into array, just disable user interaction for that button by shareButton.userInteration = NO and then add to array and then pass the array to the method defined above. By this you can be sure that button is disabled.
But please provide the sample code that you have worked so that can update your code directly.
In case if you still didn't get revert back I'll give you the working code directly here.

Two clickable items in UITableView

I have a UITableview as a contact list in which there are a lot of users. It has a thumbnail photo and profile details on each row. I want to make it like when clicking on thumbnail, it goes another page for photo and when clicking on the rest of the space it goes to somewhere else. By using table view delegate I know which row is clicked and pass data, like user id to a new ViewController. But can I know which row when the thumbnail is clicked?
I am using the tag to find the view from cell, like
UIImageView *thumbnailView = (UIImageView *) [cell viewWithTag:1];
I think I cannot label the row index by tag.
You can add gesture to thumbnail image and get events on it. Need to set tag for thumb image as per indexPath.row.
Add following code in you in cell datasource method (cellForRowIndexPath:) :
cell.YOURIMGVIEW.userInteractionEnabled = YES;
cell.YOURIMGVIEW.tag = indexPath.row;
UITapGestureRecognizer *clickable = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageClicked:)];
clickable.numberOfTapsRequired = 1;
[cell.YOURIMGVIEW addGestureRecognizer:clickable];
[clickable release];
And also used below method :
-(void)imageClicked:(id)sender
{
UITapGestureRecognizer *gesture = (UITapGestureRecognizer *) sender;
NSLog(#"image tag is = %d", gesture.view.tag);
////////
You custome come goes Here !!!!!!!!!!!!!!
///////
}
You can use the photo as accessory view. Or use a UIButton with the photograph as background and set the action accordingly. (e.g. call a method on the view controller which then performs the push or segue. Doing so you will have to pass some data to the view controller indicating which row was actually clicked in. The number of the row can be used or you can set the tag of the button with some numeric id.)
Go the Easy way because doing it hard-way won't grant you a president award, right ?
Instead of UIImageView take a UIButton and set the Image on UIButton instance.
Set Button tag as the indexPath.row so that when you retrieve it you know which row is clicked. You can also sort it the other way but it seems quiet handy.
Add target into the button to a custom function. [ btnObj addTarget ...... ]
tyepcast you sender to a UIButton and receive the tag (indexpath.row)
You can remove all gesture recognizers and buttons in tableviewcell, and in your controller, you can implement below delegate;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
To make this method triggered, you need to set tableview delegate as your controller, either via code as below, or using storyboard.
- (void)viewDidLoad {
self.tableview.delegate = self;
}
By doing this, it won't matter which item you clicked in your cell, delegate method will be called always.
I hope this helps.

Flicker when tapping on - button when table view is in edit mode

I am using a custom class which is subclassing UITableViewCell. Now, when tableview goes in edit mode, I adjust the UIComponents on the cell inside layoutSubviews of my custom class. Now, when user tap on the "-" button the layoutSubviews get called once again and the UIComponents on the cell again repositions themselves which causes a weird UI flicker. I tried with below code in layoutSubviews but then UIComponents on the cell does not reposition themselves when user tap on edit and table comes in edit mode. Is there any graceful way to handle this.
if (self.editingStyle == UITableViewCellEditingStyleDelete) {
return;
}
Ok. Found this property which is set when user tap on the - button to show the delete button:
self.showingDeleteConfirmation

How to do (custom) selection with custom UITableViewCell subclass

I have a UITableView with a custom UITableCellView subclass. I want to show one of the rows as active or selected. The controls in my cell have their own gestures, but I have area on the right where I can do the selection. I had (naively) thought I could just indicate I wanted a checkmark style accessory but Apple's docs say
This control does not track touches. The delegate of the table view
can manage check marks in a section of rows (possibly limiting the
check mark to one row of the section) in its
tableView:didSelectRowAtIndexPath: method.
I'm not sure how to interpret that, but I put the tableView:didSelectRowAtIndexPath: method in my delegate, and it never fires. Regardless of where I touch my cell (on the part where there are touchable controls or not). So I'm curious why that doesn't work? I also noticed that regardless of how I set the selected property on the cells, the checkmark always shows on, so I don't think it's really meant to be used a selection indicator.
But I'm actually kind of OK with that. I don't really want a checkmark, I'd rather do something like mail does when it does multi select on the left side, the radio-button-esque style circles. Which then leads me to a quandary about how to proceed. Should I just add a button control to the right side, manipulate the images appropriately in my custom cell subclass? Do I mess with the background image of the button in that case? Or just the image? And since selecting one needs to deselect the others, what's the best way to connect this to the table view delegate, rather than the subclass? Or should I make a custom NSView subclass?
UPDATE
I removed the accessory. I added an UIImageView to show selection state. Because the sub control in my cell uses a hold gesture, the selection tap makes it through just about everywhere for the cell. I synchronize the visual selection state using the following method:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
self.selectionView.image = self.selected ? [UIImage imageNamed: #"selected"] : [UIImage imageNamed: #"not_selected"];
}
To my custom controller, I added the following method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[Site setCurrent: self.allSites[indexPath.row]];
[[Site current] pullValves];
}
It finally donned on me that that the first method was for updating the visual state, but not for responding to the users intent, that belongs in the second method. The first fires at various times, but the second applies when the user actually does the tap.
Finally, I had to programmatically set
self.clearsSelectionOnViewWillAppear= NO;
Not matter what I set in the storyboard, that value was YES, so returning to the list was clearing my selection.
You're adding a gesture to each of the cells you create? I would back that out of there and create a gesture on the main controller which holds your tableview (not the individual cells).
Add this to your main controller so the controller can handle the gestures accordingly.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
If you need to track the cell that was touched (say, for a panning gesture), you can grab the index path given the gesture recognizer.
CGPoint p = [recognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
From there, we go back to your goal: tracking your active cell. tableView:didSelectRowAtIndexPath needs to be hit (hopefully the steps above help here). Store some sort of identifier of the item you need to keep selected. When tableView:willDisplayCell:forRowAtIndexPath is called you can trigger the selection state.

how to create tabs that expands when selected in iOS

I want to create a tableView or tabs that expands when user selects them. This is very commonly used in webpages using jquery.
you can check http://jqueryui.com/accordion/ It does exactly what i want to do in my ipad app. with horizontal tabs too http://jqueryui.com/tabs/
Can anyone tell me how to achieve this in my iPad app ? Or any pointers would be appreciated.
TIA
Sam
1.Use UITableView for first type of tab.
a) Use Header and Cell View in your desired format.
b) Hide and unhide cell view with some animation.
2.Use UISegementedControl for second type of tab.
a) Use function addTarget :
[self.mySegmentedControl addTarget:self action:#selector(segmentChanged) forControlEvents:UIControlEventValueChanged];
b) Implement segmentChanged :
- (void) segmentChanged:(UISegmentedControl *)paramSender{
//check if its the same control that triggered the change event
if ([paramSender isEqual:self.mySegmentedControl]){
//get index position for the selected control
NSInteger selectedIndex = [paramSender selectedSegmentIndex];
if (selectedIndex == 1 ) { // do required } and so on....
}
}
The best possible way is using the headerview to show the Master row and the tableview cells for showing the Details row.Write a touch event for the headerview and set it with the showing and hiding the cells ,with neat row animation.You need to keep the status of the opened and closed state of cell with an array of bools repesenting the no of masterview.

Resources