In a VC I have 2 tableViews - 1 main and other is added in a drop down menu. From drop down menu TableView "ddTableView", I have added 5 cells in Storyboard itself as prototype cells. Each cell contains an image and a Label. Have also set identifier for each cell. Have also set Accessory Type as "Disclosure Indicator" for each cell of ddTableView.
DataSource and Delegate for mainTV is set to the VC and delegate for ddTableView is set the VC. As the rows are added within the storyboard, I didn't set any datasource for ddTableView in my VC. I managed my delegate methods like this :-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == ddTableView) {
// RETURNS NIL ???
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"CELL Identifier = %#", cell.reuseIdentifier);
return cell;
} else {
}
}
-(void )tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == ddTableView) {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog (#" CELL Clicked of - %#", cell.reuseIdentifier);
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == ddTableView)
return 44;
else
return 60;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == ddTableView)
return 5;
else
return [chatMsgsArr count];
}
It does call respective delegate method. For cellForRowAtIndexPath it returns cell as nil. Why so ? And on execution, I don't see any contents of the table view - table is blank. I changed the bg color of image and text color also, but yet nothing is seen on execution.
Why so ? Where I may be going wrong ?
You have to allocate the cell, the first time cellForRowAtIndexPath is called. If the cell is not allocated it would return nil as you are getting right now.
What you need to do is allocate the cell only once, the first time you enter cellForRowAtIndexPath. After that you can reuse it as you have done.
If you are planning to use the default tableViewCell your method should look as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"your_cell_identifier_name";
if (cell == nil)
{
UITableViewCell *cell = [UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
else
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
}
//write the code to populate your cell with data here
//return the cell object
return cell;
}
Hope this helps! :)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
}
if (tableView == ddTableView) {
NSLog(#"CELL Identifier = %d", indexpath.row);
} else {
NSLog(#"CELL Identifier = %#", [chatMsgsArr objectAtIndex:indexPath.row]);
}
return cell;
}
Related
At one ViewController is located separately UITableView, UITextField and UIButton. I need to add UITextField's text to the cell of the table by button. I set the flag on the pressing process:
- (IBAction)addingButon:(id)sender {
_addingFlag = true;
}
And then in the method of the table do the following:
- (UITableViewCell *)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"dataCell";
UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:cellID];
while (true) {
if (_addingFlag && _textBox.text.length != 0) {
cell.textLabel.text = _textBox.text;
[tableView reloadData];
}
_addingFlag = false;
break;
return cell;
}
Data in table appears only when scrolling and in the strange order. Can you please tell how to fix it. Working with Objective-C just a couple of days.
tableView:cellForRowAtIndexPath: should return immediately. Instead, call [tableView reloadData] in addingButton::
- (IBAction)addingButon:(id)sender {
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"dataCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
cell.textLabel.text = _textBox.text;
return cell;
}
I've used sqlite in my project and I get ten elements in _mChats (array) successfully. The numberOfRowsInSection method returns 10 but cellForRowAtIndexPath ignores the first few rows and in simulator other elements all display on the same cell,why?
And if I use sections instead of rows to display data,everything becomes normal.
This is my code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_mChats count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
VChat *cell = [VChat vChatWithTableView:tableView];
cell.mChat = _mChats[indexPath.section];
return cell;
}
I think its because of this
cell.mChat = _mChats[indexPath.section];
Try this instead
cell.mChat = _mChats[indexPath.row];
This is because Indexpath is a property that has two values inside it,
Eg. IndexPath [section,row] meaning indexpath of something is section number 1, row number 5.
Hope this helps you understand.
This is how your cellForRowAtIndexPath should look like:
- (UITableViewCell *)tableView:(UITableView *)iTableView cellForRowAtIndexPath:(NSIndexPath *)iIndexPath {
NSString *cellIdentifier = #"myCell";
UITableViewCell *cell = (UITableViewCell *)[iTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
}
cell.mChat = _mChats[indexPath.row];
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)iTableView cellForRowAtIndexPath:(NSIndexPath *)iIndexPath
{
VChat *cell = (VChat *)[tableViewdequeueReusableCellWithIdentifier:#"CellIdentifier"];
NSArray *nib = [[NSBundle mainBundle]loadNibNamed:#"VChat" owner:self options:nil];
if (cell==nil)
{
cell = nib[0];
}
cell.mChat = _mChats[indexPath.row];
return cell;
}
The three delegate method must be implement you have wrote have something wrong. As #Abhinav said the method return cell have some thing wrong.
As the code you showed will create a new cell when a new cell present in the screen. I think the first few rows just because the cell has't be reused.
There is another thing I want to say, if you are using storyboard to build the tableview this method should seems like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// The identifier in storyboard you setted.
static NSString *cellName = #"theCell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:cellName];
if (dataSource_[indexPath.row]) {
// This method will bind data to view
[cell fillDataWithDict:dataSource_[indexPath.row]];
}
return cell;
}
I'm developing an iOS 7+ app, and I've some UITableViewController in storyboard that are showing a weird behavior. I've a basic prototype cell defined in one of them, with an identifier #"standardCell" also set in storyboard. In the associated UITableViewController class, I've this:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"standardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"%d", indexPath.row];
return cell;
}
Cells are loaded the first tiem the table view is shown, but as soon as I scroll the table content, all cell titles that were set appear empty and cellForRowAtIndexPath: is not called anymore. The didSelectRowAtIndexPath: delegate method is neither called.
I've set both delegate and dataSource for this table view to be the table view controller. And its .h file conforms to UITableViewController <UITableViewDataSource, UITableViewDelegate>.
I find a similar issue with another table view and associated view controller, where prototype cell is a custom cell instead: cells show wrong data and weird content when I scroll the table, as if cells where not being dequeued and reused as expected.
What could I being missing?
Thanks
at least in this method:
Change this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"standardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"%d", indexPath.row];
return cell;
}
To this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"standardCell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%d", indexPath.row];
return cell;
}
I have UITableView on iPad. When a cell is selected and the cell is scrolled off the screen, and then scrolled back into the screen, the selected cell is blank.
My problem occurs only on the device and not on simulator. I have tried various of the proposed solutions like manage selected index
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.selectedIndexPath = indexPath;
}
and use setSelected/selectRowAtIndexPath on cellForRowAtIndexPath like
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Desktop Row";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
...
if(self.selectedIndexPath!=nil){
if ((indexPath.row == self.selectedIndexPath.row) && (indexPath.section == self.selectedIndexPath.section)) {
[self.tableView selectRowAtIndexPath:self.selectedIndexPath
animated:YES
scrollPosition:UITableViewScrollPositionNone];
}
}
return cell;
}
But nothing works, I saw very similar questions people ask but I have something different and strage.
Any ideas will be appreciated.
So I have a subclassed UITableView that lists data. I need to make only one cell selectable.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// rows in section 0 should not be selectable
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
if (indexPath.row == 3) {
cell.userInteractionEnabled = YES;
cell.selectionStyle = UITableViewCellSelectionStyleGray;
NSLog(#"Hey whats up, address");
return indexPath;
}
else {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return nil;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
My code that does this so far works, but only after the cell is clicked at least once. Placing it in didSelectCell allows the cell to be selected if held down for 1-2 seconds.
You should do that in the cellForRowAtIndexPath. Like this:
-(UITableViewCell*)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// your code
if(indexPath.row != 3)
{
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
{
}
And then on didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.row == 3)
{
//do your stuff
{
}