Need To delete cell from UICollectionView - objective-c

I can't get out of this, I have a UICollectionView with custom cell and every cell has a X button to delete it from the list, I pass to the button.tag the IndexPath.item and on the delete function i've implemented the following method:
- (void)DeleteProductFromArray:(UIButton *)button {
NSLog(#"item: %d",button.tag);
TagHelpConverted = [NSNumber numberWithInt:button.tag];
TagHelp = button.tag;
if(DeletedCells.count == 0)
{
[DeletedCells addObject:TagHelpConverted];
}
else
{
for(int i = 0; i < DeletedCells.count; i++)
{
if([TagHelpConverted compare:DeletedCells[i]] == NSOrderedDescending)
{
TagHelp--;
NSLog(#"ho diminuito il tag di 1");
}
}
[DeletedCells addObject:TagHelpConverted];
}
NSLog(#"valore tagHelp:%d", TagHelp);
[_feedItems removeObjectAtIndex:TagHelp];
[self.customCollectionView deleteItemsAtIndexPaths:#[[NSIndexPath indexPathForItem:TagHelp inSection:0]]];
[self.customCollectionView reloadData];
}
The problem is that when scrolling the UICollectionView calls the - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { and my NSMutableArray that stores which button has already been clicked has "old values" that compared to the new ones assigned by this method makes the app delete random items inside the UICollectionView.
I searched on the Internet for help about deleting UICollectionView cells but I found almost anything, I'm struggling very hard on this one but I can't find a way to get out, please if anyone has a solution help me

To delete cells from a collectionView you can remove them from the data source and reload the collectionView. You want to make sure you keep your data source in sync with what is on the screen. Basically, keep your data source how you want it and call [collectionView reloadData].
- (void)didTapDeleteCellBtn:(UIButton *)deleteCellBtn {
UICollectionViewCell *cell = (UICollectionViewCell *)deleteCellBtn.superview.superview; // Make sure this gets the right cell for the button
NSIndexPath *indexPath = [self.customCollectionView indexPathForCell:cell];
id item = self.feedItems[indexPath.row];
NSMutableArray *updatedFeedItems = [self.feedItems mutableCopy];
[updatedFeedItems removeObject:item];
self.feedItems = [NSArray arrayWithArray:updatedFeedItems];
[self.customCollectionView reloadData];
}

Related

Showing a specific cell each scroll back on UICollectionView

I'm trying to load a custom cell each time someone scrolls up/back on my UICollectionView then if a condition is met, allow that user to see the previous items in the UICollectionView / resume normal UICollectionView behavior.
I tried subtracting the current indexpath.row, but that isn't working and I can't wrap my head around what exactly the case needs to be to make it work.
I was able to successfully get the custom cell to render as the third item (2) in the UICollectionView (shown below), but can't figure out how to make it's index path 0 and start the collection view on index path 1.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == 2) {
MyCustomCell *customCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"customCell" forIndexPath:indexPath];
return customCell;
}
else {
PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"photo" forIndexPath:indexPath];
_obj_IndexPath = indexPath;
NSLog(#"%ld",(long)_obj_IndexPath.row);
_imageView = (UIImageView *)[cell viewWithTag:200];
_imageView.image = [UIImage imageNamed:[_imageArray objectAtIndex:indexPath.row]];
return cell;
}
}
The goal is a normal UICollectionView functionality with "full-screen" cells that scroll vertically AND during a certain condition scrolling to the previous cell is limited to only one scroll back AND that cell has a special / custom view on top of the cell content.
Any help or ideas would be awesome. Thank you!
I've updated my current code per comments below

UITableView accessoryType disappears in last half of UITableView

I have an iPad app (XCode 4.6, ARC, Storyboards, iOS 6.2.3). I have a UIPopover with a UITableView that has 21 rows in it. I can set the accessoryType in all of the rows randomly, but only in the first 12 rows does the accessoryType setting (checkmark) persist so it can be examined in another method and processed. I don't see any difference between the first 12 rows and the last 9 rows. The UITableView is scrollable, so to get to the rows after the 11th row, you have to scroll to the bottom
Here is the code to set the accessoryType:
#pragma mark didSelectRowAtIndexPath
- (void) tableView:(UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
// get the cell that was selected
UITableViewCell *theCell = [tableView cellForRowAtIndexPath:indexPath];
if(theCell.accessoryType != UITableViewCellAccessoryCheckmark)
theCell.accessoryType = UITableViewCellAccessoryCheckmark;
else
theCell.accessoryType = UITableViewCellAccessoryNone;
}
Here is the code where I check the accessoryType and process it:
-(void) moveServices { // (moves checked tableViewRows to services tableview)
NSMutableString *result = [NSMutableString string];
for (int i = 0; i < [servicesArray count]; i++) {
NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];
[tvServices scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
UITableViewCell *cell = [tvServices cellForRowAtIndexPath:path];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
[result appendFormat:#"%#, ",cell.textLabel.text];
NSLog(#"\n\ni: %d\ncell.accessoryType: %d\ncell.textLabel: %#",i,cell.accessoryType, cell.textLabel);
}
}
if (result.length > 2) { // move to text box in main menu
storeServices =[result substringToIndex:[result length] - 2];
}
}
It looks like you're mixing the notion of "data source" and the contents of the cells in the table. Don't do that -- keep your data source (whether or not a particular row in the table should display a checkmark based on your program logic) separate from the settings of particular cells (whether or not a particular cell displays a checkmark). Then in cellForRowAtIndexPath, you build the cell to match your data source's current settings. The reason is that UITableView reuses cell instances based on which rows are visible on-screen (and it's just good MVC design).
In your case you should keep an NSMutableArray property in your class that records the settings for the entire table, and use the value from that array in cellForRowAtIndexPath to set up that particular cell. Then the other "business logic" methods in your controller use the array property to query your model state instead of the cell settings (which are part of the view and should be independent from the data model).

Cell selection issue with EasyTableView

I have what must be a simple problem with EasyTableView (https://github.com/alekseyn/EasyTableView)
I have a number of horizontally scrolling tables that function properly.
I am able to select a cell and perform a segue, however, once the new view controller is dismissed, I am no longer able to select that cell and perform the same action until I have selected another cell in the same table.
My question is: How can I deselect previously selected the cell programmatically to renable this particular action.
Thanks in advance!
The selectedIndexPath is intentionally persistent in case a user scrolls the selected tableview cell offscreen and then back again. If you don't want this persistence please add the line shown below, after the delegate method (in EasyTableView.m):
- (void)setSelectedIndexPath:(NSIndexPath *)indexPath {
if (![_selectedIndexPath isEqual:indexPath]) {
NSIndexPath *oldIndexPath = [_selectedIndexPath copy];
_selectedIndexPath = indexPath;
UITableViewCell *deselectedCell = (UITableViewCell *)[self.tableView cellForRowAtIndexPath:oldIndexPath];
UITableViewCell *selectedCell = (UITableViewCell *)[self.tableView cellForRowAtIndexPath:_selectedIndexPath];
if ([delegate respondsToSelector:#selector(easyTableView:selectedView:atIndexPath:deselectedView:)]) {
UIView *selectedView = [selectedCell viewWithTag:CELL_CONTENT_TAG];
UIView *deselectedView = [deselectedCell viewWithTag:CELL_CONTENT_TAG];
[delegate easyTableView:self
selectedView:selectedView
atIndexPath:_selectedIndexPath
deselectedView:deselectedView];
// Add this line here!
_selectedIndexPath = nil;
}
}
}

Objective C - iOS, iterate through UILabels within static table cells off screen

I have a UITableView made of static cells, and each cell contains a UILabel which is populated with field data when the screen loads. There are more cells than can fit on one screen, so the table view scrolls. The UILabels are hidden at design-time and I want to set them visible once all the text properties have been set. I've been using the subviews property of the tableView to iterate through the labels to setHidden:NO but this only affects the labels within cells that are currently in view. How can I iterate through all the UILabels regardless of which ones are in view or not?
Thanks
Jonathan
You can address this issue inside your tableView:cellForRowAtIndexPath: method.
Assuming that you have implemented your static cells the way Apple's guide suggests, your tableView:cellForRowAtIndexPath: should look like a sequence of if-then-else statements returning the cells provided through IBOutlet objects:
if (indexPath.row == 0) {
return cell1;
} else if (indexPath.row == 1) {
return cell2;
} // .. and so on
Modify this code as follows:
UITableViewCell *res = nil;
if (indexPath.row == 0) {
res = cell1;
} else if (indexPath.row == 1) {
res = cell2;
} // .. and so on
// Call your custom code that makes the label visible
if (allTextPropertiesHaveBeenLoaded) {
[res setMyLabelVisible];
}
return res;
When all text properties have been set, call reloadData to force all cells to go through your tableView:cellForRowAtIndexPath: and get reconfigured.
just call upon the cellForRowAtIndexPath: method
for(NSUInteger i = 0; i < numberOfCells; i++) {
UITableView* cell = [tableView cellForRowAtIndexPath: [NSIndexPath indexPathForRow:i inSection:0];
}

difference between indexPath and indexPath.row (iphone)

i am confused about indexPath and indexPath.row, does each cell of a tableView correspond to an indexPath? so why do we look for the "row" of this indexPath? i checked the doc but i think it confuses me.
i found this code :
// this method is used in case the user scrolled into a set of cells that don't have their app icons yet
- (void)loadImagesForOnscreenRows
{
if ([self.entries count] > 0)
{
NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visiblePaths)
{
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
if (!appRecord.appIcon) // avoid the app icon download if the app already has an icon
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
}
}
}
Can you explain me the difference between the two?
Thanks a lot
Paul
Each instances of NSIndexPath class has two properties: row and section (Documentation)
Each cell of tableView corresponds to unique indexPath (N-th row in M-th section). Often there is only one section and people use only row to reference to the data.