As AQGridview borrows a lot of it's ideas from UITableView so I think the answer should apply to both.
I have a custom cell with the following objects inside:
label
favourite button (can be turned on/off by the user and I use .selected = YES/NO)
The problem is maintain the state of the button when scrolling. Below is my 'cellForItemAtIndex' method.
- (AQGridViewCell *) gridView: (AQGridView *) aGridView cellForItemAtIndex: (NSUInteger) index
{
static NSString * cellIdentifier = #"CellIdentifier";
SampleGridViewCell * cell = (SampleGridViewCell *)[aGridView dequeueReusableCellWithIdentifier:cellIdentifier];
if ( cell == nil )
{
cell = [[SampleGridViewCell alloc] initWithFrame: CGRectMake(0.0, 0.0, 200, 60) reuseIdentifier: cellIdentifier];
}
NSDictionary *item = [self.items objectAtIndex:index];
NSString *title = [item objectForKey:#"title"];
cell.index = index;
cell.titleLabel.text = title;
//cell.favButton.selected = (logic goes here);
return cell;
}
Somehow I need to keep a reference in my viewcontroller of when an item has been favourited so that I can turn the button on/off when the cell is recreated in this method.
Do I do an addTarget on cell.favButton with a method in the vc? But then how do I get a reference to the index of the button?
Has someone implemented something similar?
As you said, add a target to you button to whatever method you want. In that method, you can then get the rows index by using
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:tableview];
NSIndexPath *indexPath = [tableview indexPathForRowAtPoint: currentTouchPosition];
NSUInteger row = [indexPath row];
From there you can then store that the button has been pressed in your existing data set that is being used by the table itself.
Then when the table gets loaded, and you retrieve your data, simply enable/disabled the cells button based on the data you've got stored for that row :)
Related
I have UICollectionView that has two UICollectionResuabeView(Custom View) and one UICollectionViewCell. The form a single entity in UICollectionView. I put Delete button on one of UICollectionResuabeView and by pressing it want to delete the row (if i call it right).
This is the screenshot form Storyboard:
I tried getting section of it my many means, but non works. Guess I just dont have enough knowledge of how UICollectionView works. Here is some code I tried:
I know its I mess, but at least I was trying ))
I ve tried this toget indexPath, but none works.
-(IBAction)deletePressed:(UIButton* )sender{
RecipeCollectionHeaderView *contentView = (RecipeCollectionHeaderView *)[sender superview];
RecipeViewCell *cell = (RecipeViewCell *)[contentView superview];
cell = (RecipeViewCell *)[contentView superview];
// determine indexpath for a specific cell in a uicollectionview
NSIndexPath *editPath = [self.collectionView indexPathForCell:cell];
NSInteger rowIndex = editPath.row;
NSInteger secIndex = editPath.section;
// NSIndexPath *indexPath = nil;
// indexPath = [self.collectionView indexPathForItemAtPoint:[self.collectionView convertPoint:sender.center fromView:sender.superview]];
// NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
// NSSet *touches = [event allTouches];
//
// UITouch *touch = [touches anyObject];
//
// CGPoint currentTouchPosition = [touch locationInView:self.collectionView];
//
// NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint: currentTouchPosition];
NSLog(#"IndexPath CollectionView %ld", (long)rowIndex);
}
I also tried make it work like in this post, but it does not give a result:how to access from UICollectionViewCell the indexPath of the Cell in UICollectionView
Thank you all!
EDIT!
I found this works well:
-(IBAction)deletePressed:(UIButton* )sender{
[self.ordersArray removeObjectAtIndex:0];
[self.collectionView reloadData];
}
The only thing I need now is to get section of UICollectionView by UIBotton that been pressed, to delete section I want. How to do it?)
You also need to remove item from the array and UICollectionView as well.
Try to use this code.
-(void) deleteRow:(NSInteger)index {
[self.contentView performBatchUpdates:^{
[arrayForRows removeObjectAtIndex:i];
NSIndexPath *indexPath =[NSIndexPath indexPathForRow:i inSection:0];
[self.contentView deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
} completion:^(BOOL finished) {
}];
}
For cell selection use this code snippet:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
//Item position that you would like to delete.
indexPath.row;
}
Suppose that I have a custom UITableViewCell contains UIButton control. When the user presses the button it should present another view controller with the appropriate info according to which cell was chosen (to be more precise, I have an array of objects used to represent information in the UITableView and I want to transfer this info to the next view controller). The question is how can I detect button on which cell was exactly selected?
Thanks in advance.
There are many ways of doing this.. but the way of superView is no more available since iOS8. I am sharing a code which is working perfect in all iOS.
Write this selector on your cellForRow method
[cell.btnOnCell addTarget:self action:#selector(btnAction:event:) forControlEvents:UIControlEventTouchUpInside];
Now write this method
-(void)btnAction: (UIButton *)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tblView];
NSIndexPath *indexPath = [self.tblView indexPathForRowAtPoint:currentTouchPosition];
NSLog(#"%li",(long)indexPath.row);
}
Try this:
Insert below code in cellForRowAtIndexpath
[cell.yourbuttonName addTarget:self action:#selector(yourbuttonNamePressed:) forControlEvents:UIControlEventTouchDown];
paste the below code as separate method
- (void)yourbuttonNamePressed:(UIButton *)sender
{
CGPoint swipepoint = sender.center;
CGPoint rootViewPoint = [sender.superview convertPoint:swipepoint toView:self.goalsTable];
NSIndexPath *indexPath = [self.goalsTable indexPathForRowAtPoint:rootViewPoint];
}
Simple solution is that when you configure cell in CellForRowAtIndexPath there you need to set the cell.button.tag=100+indexPath.row.
-(void)btnClicked:(UIButton *)sender
{
NSIndexPath* path= [NSIndexPath indexPathForRow:sender.tag-100 inSection:0];
UITableViewCell*cell=(UITableViewCell *)[tblView cellForRowAtIndexPath:path];
}
NOTE: you need to remove addTarget and buttonClicked implementation from UITableviewcell
and in cellForRowAtIndexPath method addtarget to button and in this class implemnt buttonClicked Method.**
I am using a UITableViewCell subclass in a highly customized UITableView. Now I want to implement a edit button. So I implemented a button, an action, setting the UITableview to editing:YES and so on. The problem is that my cells do not show the delete or move buttons or handlers. Do I need to implement something in my subclass for this?
Bests,
Philip
do like this complete implementation of edit and delete buttons in tableview, customize according to your requirement
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"Referrral RemainderCC";
referrralRemainderCC *cell = (referrralRemainderCC *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
UIViewController *c = [[UIViewController alloc] initWithNibName:#"referrralRemainderCC" bundle:nil];
cell = (referrralRemainderCC *) c.view;
}
if (dataArray.count==0) {
return 0;
}
else
{
referralDC *referral =[dataArray objectAtIndex:indexPath.row];
cell.lblDate.text = referral.referralDC_Date;
cell.lblCompanyName.text = referral.referralDC_CompanyName;
cell.lblEmail.text = referral.referralDC_EmailTelephone;
cell.lblFellowUpDate.text = referral.referralDC_FellowUpDate;
cell.lblReferralRequest.text =referral.referralDC_ReferralRequest;
cell.lblName.text = referral.referralDC_Name;
cell.edit.tag = indexPath.row;
cell.delete.tag = indexPath.row;
[cell.edit addTarget:self action:#selector(btnTapped:withEvent:) forControlEvents:UIControlEventTouchUpInside];
[cell.delete addTarget:self action:#selector(btnTapped:withEvents:) forControlEvents:UIControlEventTouchUpInside];
}
return cell;
}
- (void)btnTapped:(id)sender withEvent:(UIEvent*)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.tblView];
NSIndexPath *indexPath = [self.tblView indexPathForRowAtPoint:location];
referralDC *referral =[dataArray objectAtIndex:indexPath.row];
referalID = referral.referralDC_ReferralID;
txtDate.text = referral.referralDC_Date;
txtCompanyName.text = referral.referralDC_CompanyName;
txtEmail.text = referral.referralDC_EmailTelephone;
txtFolowUpDate.text = referral.referralDC_FellowUpDate;
txtviewReferralRequest.text =referral.referralDC_ReferralRequest;
txtName.text = referral.referralDC_Name;
btnEditPressed=1;
}
my app was running fine under ios6.1. tried the ios7 simulator and the following part does not work:
EditingCell *cell = (EditingCell*) [[textField superview] superview];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
NSLog(#"the section is %d and row is %d", indexPath.section, indexPath.row);
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *rowKey = [[keysForRows objectAtIndex: section] objectAtIndex: row];
It always comes:
the section is 0 and row is 0
although another section / row were selected.
Has someone an idea why this does not work under ios7?
Your approach to find the "enclosing" table view cell of a text field is fragile,
because is assumes a fixed view hierarchy (which seems to have changed between
iOS 6 and iOS 7).
One possible solution would be to traverse up in the view hierarchy until the table view cell is found:
UIView *view = textField;
while (view != nil && ![view isKindOfClass:[UITableViewCell class]]) {
view = [view superview];
}
EditingCell *cell = (EditingCell *)view;
A completely different, but often used method is to "tag" the text field with the row
number:
cell.textField.tag = indexPath.row; // in cellForRowAtIndexPath
and then just use that tag in the text field delegate methods.
I was finding cells the same way you were. Now I use this quick method if I have a button in a cell and know the tableview I'm in. It'll return the tableviewcell.
-(UITableViewCell*)GetCellFromTableView:(UITableView*)tableView Sender:(id)sender {
CGPoint pos = [sender convertPoint:CGPointZero toView:tableView];
NSIndexPath *indexPath = [tableView indexPathForRowAtPoint:pos];
return [tableView cellForRowAtIndexPath:indexPath];
}
Experiencing this problem in iOS 11, but not in 9 or 10, I overrode the func indexPath(for cell: UITableViewCell) -> IndexPath? method using the technique that #drexel-sharp detailed previously:
override func indexPath(for cell: UITableViewCell) -> IndexPath? {
var indexPath = super.indexPath(for: cell)
if indexPath == nil { // TODO: iOS 11 Bug?
let point = cell.convert(CGPoint.zero, to: self)
indexPath = indexPathForRow(at: point)
}
return indexPath
}
My question is clear,
I have a UITableView and UIMapView with annotations, when an annotation is tapped on the map, it will be found on the table and be selected since the user can recognize it.
But, if i try something it is only in visible cells, i am not able to do as i expected.
- (void)annotationTapped:(UITapGestureRecognizer *)recognizer{
if ( recognizer.state == UIGestureRecognizerStateEnded ) {
//NSLog(#"%#",[recognizer.view subviews]);
UIImageView *temp = (UIImageView*)[recognizer.view viewWithTag:1000];
UILabel *temp2 = (UILabel*)[temp viewWithTag:1001];
NSArray *tapAndFind;
if(isFiltered)
{
tapAndFind = filteredListContent;
}
else
{
tapAndFind = eczaneler;
}
for(int i=0;i<tapAndFind.count;i++)
{
Pharma *tempPharm = [tapAndFind objectAtIndex:i];
if([tempPharm.CustomerIndex isEqualToString:temp2.text])
{
EczaneCell *cell = (EczaneCell*)[tableView1 cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
for(EczaneCell * cell2 in [tableView1 visibleCells])
{
cell2.selected = NO;
}
cell.selected = YES;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[tableView1 indexPathForCell:cell].row
inSection:[tableView1 indexPathForCell:cell].section];
[tableView1 scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
}
}
}
This is because your UITableView is just a presentation of your data, not a data itself. So, when you tap on annotation, you should somehow find a correspondence with a data, the position of your annotation data in collection. Then you may calculate/find out the index of row in table, and then you can perform UITableView's scrollToRowAtIndexPath:atScrollPosition. Alternatively, you can mark the cell to make it distinguishable.
In your code
EczaneCell *cell = (EczaneCell*)[tableView1 cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
can return nil for cell when the cell for given index path is invisible. That's why you should check against data, not table cells.