How to select row in uitableview programmatically based on NSString - ios

I have a uitableview that hosts a number of cells, in another part of the app the user will make an NSString selection that will match on of the cells in the uitableview, how can I select hat cell programmatically?
I tried using the method
selectRowAtIndexPath:animated
but how can I get the indexpath? is there a better way?

I think you are loading data from an array. Then just search inside that NSArray and take index of the matched object. Now you can create NSIndexPath programatically:
[NSIndexPath indexPathForRow:index inSection:section];
Just use this NSIndexPath to select the row

try this .... first try to get the cell number based on string
NSString * pUserSelectedString = #"abcd";
int index;
if([array containsObject:pUserSelectedString])
{
index = [array indexOfObject:pUserSelectedString];
}

The way you needs to get the indexpath from source array is
int selectionIndex;
if([sourceArray containsObject:userSelectionString])
{
selectionIndex = [sourceArray indexOfObject:userSelectionString];
}
You have to check whether selection object is there or not before get the indexpath from sourceArray.then you have to use this indexpath for selectRowAtIndexpath:animated method

Related

Can you downcast a NSIndexPath to NSInterger

I have a AVPlayer class that I'm using in a detail view that takes a indexPath of type Int.
I am getting the indexPath from the table view tableViewDidSelectAtIndexPath before sending it to the detail VC to use.
I tried to just simply downcast the NSIndexPath as! NSInteger before sending it to detail VC to use but it crashes without a crash message. So Im a bit stuck as to how to go about this.
Is it possible to downcast this? How can I get the number out of the NSIndexPath into an Int so I can use it in my class?
Objective C
NSInteger currentRow = indexPath.row;
Swift
let currentRow = self.tableView.indexPathForSelectedRow().row
NSIndexPath is always* a combination of section and either row (for UITableView) or item (for UICollectionView).
you need to dissolve the section by accessing the single index:
id object = [[self dataSource] objectAtIndex:[indexPath row]];
* EDIT
Respective the comments: you are right. Multiple indexes are possible with NSIndexPath.
If you know you have multiple indexes (what I wouldn't expect in UITableViewDelegate) you can iterate the indexes:
for (int i = 0; i < [indexPath length]; i++) {
NSUInteger index = [indexPath indexAtPosition:i];
// use index to access whatever you want
}
EDIT
PLEASE read documentation and headers before you ask the next time. Little hint: cmd-click NSIndexPath will take you to its header file with all possible informations.

iOS: reload single cell of UICollectionView

I am trying to follow the following post on reload a cell in a UICollectionView:
UICollectionView update a single cell
I know that I ultimately want something that looks like this:
[self.collectionView reloadItemsAtIndexPaths:??];
But I don't know how to find and pass the indexPath of a particular cell. Can anyone provide any pointers?
I have an NSMutableArray that contains all the cell information (imageViews that are generated in each cell). Ideally, what I'd like to do is pass the index of the NSMutableArray to refresh the corresponding cell on the page. But I'm not sure how the numerical index gets translated into an indexPath.
Thanks in advance for your help!
It depends on your implementation and how you have grouped your cells into sections but let's assume you have one section and each element in your array corresponds to a row in your table.
If you wanted to reload a cell corresponding to an array element at index x all you need to do is write
[_collectionView performBatchUpdates:^{
[_collectionView reloadItemsAtIndexPaths:#[[NSIndexPath x inSection:0]]];
} completion:^(BOOL finished) {}];
Conversely, if you have the cell but want to find its index path you can always call [collectionView indexPathForCell:myCell]
Toy have to pass an array containing the indexPaths that you want to be reloaded.
[self.collectionView reloadItemsAtIndexPaths: indexpathArray];
NSIndexPath has some property names section and row, both represents a cell. If your collection view has single section, you can create a NSIndexPath by setting its section = 0;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:0];
Here rowIndex is your array index. Btw you have to make an array with you newly created indexpaths, then pass it to reloadItemsAtIndexPaths.
Hope this helps.. :)
Obj-C
NSMutableArray *indexPaths = [[NSMutableArray alloc] init]
[indexPaths addObject:indexPath];
[self.collectionView reloadItemsAtIndexPaths: indexPaths];
Swift 4.0
var indexPaths = [IndexPath]()
indexPaths.append(indexPath)
if let collectionView = collectionView {
collectionView.reloadItemsAtIndexPaths(indexPaths)
}
You can use this way for Swift 5.1:
collectionViewOutletName.reloadItems(at: [IndexPath(row: indexNumber, section: sectionNumber)] )
You can use this way for Swift 5:
CollectionView.reloadItems(at: IndexPath])
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *dic = #{#"option":[NSNumber numberWithBool:YES]};
[self.array insertObject:dic atIndex:indexPath.row];
[collectionView reloadItemsAtIndexPaths:#[indexPath]];
}

UICollectionView, scrolling to an Item without knowing its NSIndexPath

I have a UIcollectionview that shows an array of objects called Items.
At one point in the lifecycle of my app I do need to move the collectionview ( or scroll it ) to a specific Item that I receive Via NSnotification. I do not know the NSIndexPath of that Item but its definitely available in the collectionview.
I tried
NSIndexPath *myIndexPath = [NSIndexPath indexPathForItem:myItem inSection:1];
[self.collectionView scrollToItemAtIndexPath:myIndexPath
atScrollPosition:UICollectionViewScrollPositionCenteredVertically
animated:NO];
But this gives back an arbitrary number and not relevant.
How can I do that?
I dont know details of code so i am generalising my answer.
You can have a unique property for myItem say ID.
If you are maintaining an array of items say : myItemArray, and populating collection view in same order then following can work:
NSArray* myItemArray; //array used to populate collectionView
NSIndexPath *myIndexPath; //this is what we need to know
int index = 0;
//myItem is object of item type & notifiedItem is notified item
for (Item* myItem in myItemArray) {
if (myItem.ID == notifiedItem.ID) {
myIndexPath = [NSIndexPath indexPathForItem:index inSection:1];//you got the index path right
break;
}
index++;
}
//use the index path

how to populate a static UITableView

I tried several ways but it seems I'm missing something..
Here is the code I use:
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
for (int idx=0; idx<16; idx++) {
NSIndexPath *indexPath = [[NSIndexPath alloc] initWithIndex:idx];
[self.tableView cellForRowAtIndexPath:indexPath].detailTextLabel.text = [param objectAtIndex:idx];
}
self.detailDescriptionLabel.text = [self.detailItem description];
}
}
I call this on viewDidLoad. My tableview has 16 static cells, and I'm using standard "Subtitle" type cell, so no customization needed on that front. textLabel.text is filled at design time. Also my tableview is in a tableViewController. I also tried with standard population of tableview but it seems static cells don't agree with that way.
What am I doing wrong?
#jrturton I did some changes to see what's going on:
I added these three lines under for line to see if there's anything there:
UITableView *tv = self.tableView;
UITableViewCell *cell = [tv cellForRowAtIndexPath:[NSIndexPath indexPathForRow:idx inSection:0]];
NSString *label = [[NSString alloc] initWithString:cell.textLabel.text];
First of all tv is assigned correctly, I can see that. But other than that cell and label comes empty. Even tv has no row information it seems..
Could it be because tableview has datasource and delegate assigned to the tableviewcontroller.. I think I heard it shouldn't be like that or something...
#jrturton Here it is:
Hope this helps.
Some logging would quicky show you that your index path is not valid and therefore no cell is being returned.
To create an NSIndexPath for use in a UITableView, use this method:
[NSIndexPath indexPathForRow:idx inSection:0];
The index path has to contain a row and section for the table to understand it.
You also need to call this from viewWillAppear: rather than viewDidLoad, the static table is not populated that early on. And you must call [super viewWillAppear:animated] first!

How to get indexPath.row of tableView which is currently being displayed?

I have a tableView with many values.
I want to get the first indexPath.row value of the table which is being displayed currently.
How can I do that?
I get Following Error while implementing krishnabhadra's answer:
Line at which the error comes is:
[self.table scrollToRowAtIndexPath:indexVis atScrollPosition:UITableViewScrollPositionTop animated:YES];
ERROR:
Assertion failure in -[NSIndexPath row], /SourceCache/UIKit_Sim/UIKit-1447.6.4/UITableViewSupport.m:2018
2011-04-01 11:57:25.458 GlossaryPro[1525:207] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid index path for use with UITableView. Index paths passed to table view must contain exactly two indices specifying the section and row. Please use the category on NSIndexPath in UITableView.h if possible.'
What could be wrong?
You can use tableView indexPathsForVisibleRows function, which returns an NSArray of NSIndexPath for all visible UITableViewCell. From indexPath.row you can find your array index.
NSArray *visible = [tableView indexPathsForVisibleRows];
NSIndexPath *indexpath = (NSIndexPath*)[visible objectAtIndex:0];
indexPath.row will give you index of first object displayed.
[self.myTableView visibleCells];
NSArray *anArrayOfIndexPath = [NSArray arrayWithArray:[self.myTableView indexPathsForVisibleRows]];
NSIndexPath *indexPath= [anArrayOfIndexPath lastObject];
Hope this will help you.
you can use indexPathsForVisibleRows
Returns an array of index paths each identifying a visible row in the receiver.
- (NSArray *)indexPathsForVisibleRows
Return Value
An array of NSIndexPath objects each representing a row index and section index that together identify a visible row in the table view. Returns nil if no rows are visible.
You can use: [self.tableView visibleCells]
That will return a nsarray of UITableViewCell objects, each representing a visible cell in the receiving table view.
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UITableView_Class/Reference/Reference.html
Get exact index number at center currently being displayed:
let middleIndex = ((tableView.indexPathsForVisibleRows?.first?.row)! + (tableView.indexPathsForVisibleRows?.last?.row)!)/2
Example:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let middleIndex = ((tableView.indexPathsForVisibleRows?.first?.row)! + (tableView.indexPathsForVisibleRows?.last?.row)!)/2
print(middleIndex)
}

Resources