Detailtext is not showing in case? - objective-c

I have a case but the detailtext is not showing? Does anyone know what te problem is?
i used: UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *controller;
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
switch(indexPath.row) {
case 0:
{
NSLog(#"Case 0");
controller = [[wed1 alloc] init]; //WithStyle:UITableViewStylePlain];
[self.navigationController pushViewController:controller animated:YES];
cell.detailTextLabel.text = #"Wedstrijden!";
}
break;

case 0:
{
NSLog(#"Case 0");
controller = [[wed1 alloc] init]; //WithStyle:UITableViewStylePlain];
//created a controller
[self.navigationController pushViewController:controller animated:YES];
//at his point, you are showing next ViewController's view
cell.detailTextLabel.text = #"Wedstrijden!";
//here you are changing the text of the text for current tableView's cell (which is actually going to be off the screen as new controller's view will be shown after previous statement execution)
}
with the piece of code you shared - I don't find anything wrong here, the detail text should not be visible as this view will be gone.

I don't fully understand why you'd want to set the detail text on a cell after pushing a new view controller. As samfisher said, when the user presses the first cell, in case 0, the new view controller will be alloc'd, init'd and then pushed, and after that you set the detail text to "Wedstrijden".
I'm assuming you're probably just confused between which property to use. My question to you is: when and where do you want this text to appear?

If the cell was created with the style UITableViewCellStyleDefault, the detail text label isn't displayed. In tableView:cellForRowAtIndexPath: implementation, you may create the cell with style UITableViewCellStyleSubtitle or UITableViewCellStyleValue1.

Use UIListContentConfiguration instead, or subtitle won't show.
#import <UIKit/UIListContentConfiguration.h>
And in the cellForRowAtIndexPath method:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"AddressCell" forIndexPath:indexPath];
if(cell==nil){
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"AddressCell"];
}
NSRange range = [self.dataArray[indexPath.row] rangeOfString:#","];
NSString *street;
NSString *restAddress;
if (range.location != NSNotFound) {
street = [self.dataArray[indexPath.row] substringToIndex:range.location];
restAddress= [self.dataArray[indexPath.row] substringFromIndex:range.location + 1];
}
UIListContentConfiguration *configuration = cell.defaultContentConfiguration;
configuration.text=street;
configuration.image=kImage(#"Location");
configuration.secondaryText=restAddress;
cell.contentConfiguration = configuration;
return cell;
}
Will look like this:

Related

Default CellAccessory

How can I set first row of tableview checkmarked when the app started? I mean when I start app now, there are few rows in tableview and when I click on some of them its accessory change to checkmark. When click another one, the another one comes checkmarked and previous checkmark dissapears. So now I want first row of tableview to be checkmarked when app is started and then when I click another row it 'uncheckmark' and 'checkmark' new row etc...
Try the options suggested in these posts how to apply check mark on table view in iphone using objective c? or iPhone :UITableView CellAccessory Checkmark
Basically you need to keep track of the checkmarks using say a dictionary or so. And In viewDidLoad or init method make the first cell as checked in the dictionary. While drawing cells, always check if the corresponding entry in the dictionary is checked or not and display check mark accordingly. When user taps on a cell, modify the value in dictionary to checked/unchecked.
Update:
Here is a sample code.
In .h file declare a property as
#property(nonatomic) NSInteger selectedRow;
Then use the below code,
- (void)viewDidLoad {
//some code...
self.selectedRow = 0; //if nothing should be selected for the first time, then make it as -1
//create table and other things
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// create cell and other things here
if (indexPath.row == self.selectedRow)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// some other code..
if (indexPath.row != self.selectedRow) {
self.selectedRow = indexPath.row;
}
[tableView reloadData];
}
You could set an integer to a variable similar to "checkedCell", have that value default to cell 0, and in the cellForRowAtIndexPath check to see if the cell is already checked, if not change the accessory to make it checked and update your variable.
-(void)viewWillAppear{
currentCheckedCell = 0;
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//
// Create cells -- if indexpath.row is equal to current checked cell reload the table with the correct acessories.
//
static NSString *cellIdentifier = #"RootMenuItemCell";
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:#"MyCell" owner:self options:nil];
for (UIView *view in nibContents) {
if ([view isMemberOfClass:[MyCell class]]) {
cell = (MyCell *)view;
break;
}
}
//OTHER CELL CREATION STUFF HERE
// cell accessory
UIImage *accessory = [UIImage imageNamed:#"menu-cell-accessory-default.png"];
UIImage *highlighted = [UIImage imageNamed:#"menu-cell-accessory-selected.png"];
if(indexPath.row == currentCheckedCell){
//DEFAULT ACCESSORY CHECK
// cell.accessoryType = UITableViewCellAccessoryCheckmark;
UIImageView *accessoryView = [[UIImageView alloc] initWithImage:accessory highlightedImage:highlighted];
}else{
//DEFAULT ACCESSORY NONE
// cell.accessoryType = UITableViewCellAccessoryNone;
UIImageView *accessoryView = [[UIImageView alloc] initWithImage:accessory highlightedImage:accessory];
}
[cell setAccessoryView:accessoryView];
}
return cell;
}
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//UPDATE SELECTED CELL & RELOAD TABLE
currentCheckedCell = indexPath.row;
[self.tableview reloadData];
}
Also worth noting that my examples uses custom images for accessories.
If you check out the link #ACB provided you'll find a very similar concept.
You can use,
if (firstCellSelected)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
Set the firstCellSelected flag in viewDidLoad method.

why UITableView is showing data when I touch it?

I have a UITableView loading some tweets, all works nicely but when I populate the table it doesn't enter to the CellForRow method til I touch the table view.... does somebody know how to solve this?
tab = [[UITableView alloc] initWithFrame:CGRectMake(10, 300, 400, 200) style:UITableViewStylePlain];
tab.dataSource = self;
tab.delegate = self;
then...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"entra a cellula");
Tweet *t = [tweets objectAtIndex:indexPath.row];
static NSString *MyIdentifier = #"MyIdentifier";
// Try to retrieve from the table view a now-unused cell with the given identifier.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
// If no cell is available, create a new one using the given identifier.
if (cell == nil) {
// Use the default cell style.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:MyIdentifier];
}
cell.textLabel.text = t.screenName;
cell.detailTextLabel.text = t.text;
cell.imageView.image = t.profileImage;
return cell;
}
Best guess based on what we know is that you aren't adding the table as a subview on the main thread. This means that redrawing doesn't occur until you scroll. Try wrapping the addsubview call in a GCD call like so:
dispatch_async(dispatch_get_main_queue(), ^() {
[self addSubview:tab];
});
When you finished loading your tweets call this method:
[tab reloadData];
to reload your tableView data source.

TableView: didSelectRowAtIndexPath, How to catch a row name

I fill my tableView with random data. So i don't know how many row i have and how to redirect it to screen i want to. I filled:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyClass *currentScreenElement = [self.tableRows objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:currentScreenElement.objectName];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:currentScreenElement.objectName];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.textLabel.text = currentScreenElement.objectName;
return cell;
}
And this works fine. I have a tableView with filled rows. Now i want to redirect to new screen and I doing it with:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NewScreenClass *myScreen = [[NewScreenClass alloc] init];
self.detailViewController = [[CreateView alloc] initWithScreenDef:[myScreen returnScreenFromName:#"second"]];
[self.navigationController pushViewController:self.detailViewController animated:YES];
}
Of course i know that what I actualy do here is create the same screen for every row. But how can i redirect to screen i want to?
My currentScreenElement object contains properties: objectName (display name in tableView) and objectTarget (screen definition). Both NSString.
And my question is should i save a my currentScreenElement to row patch somehow or maybe I should catch a objectName from dislay name?
In didSelectRowAtIndexPath you can get the cell by using
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
Then just get the text from the cell.
cell.textLabel.text
Why can't you use the self.tableRows array again?
MyClass *currentScreenElement = [self.tableRows objectAtIndex:indexPath.row];
NSString *title = [currentScreenElement objectName];
It's the same thing you did to setup that row, just use it again.

Can't reach the right text of a UITextField object in a modal UITableViewController subclass

I've got a sublass of UITableViewController which I use to add a new data for a new cell within another Table. That means, I've got a "Cancel" and a "Save" button at the top to save the data and get back to the table where to add the new object into. I show the adding controller modally.
My problem is though that I don't know how to get the data from the user input cells of the tableView in my UITableViewController subclass to save them in my CoreData file.
Here's the code how I try it - but at the console I just get (nil) for the persons name:
- (void)save
{
NSLog(#"Saving ...");
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
UITableViewCell *cell = [self tableView:[self tableView] cellForRowAtIndexPath:indexPath];
NSString *personName = [[cell textField] text];
NSLog(#"New Person: %#", personName);
// Do saving with Core Data and updating here.
[self dismissModalViewControllerAnimated:YES];
}
I guess you will also need the following method to understand the problem:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
EditableDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[EditableDetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryNone;
if (indexPath.section == 0) {
[cell.textField setPlaceholder:#"Name"];
} else {
switch (indexPath.row) {
case 0:
[cell.textField setPlaceholder:#"Birth Year"];
break;
case 1:
[cell.textField setPlaceholder:#"Weight in kg"];
break;
case 2:
[cell.textField setPlaceholder:#"Height in cm"];
break;
case 3:
[cell.textField setPlaceholder:#"Sex"];
break;
default:
break;
}
}
return cell;
}
I really can't find the failure. In my understanding it should work this way ... but it doesn't. Could anyone please help?
Don't call your table view datasource method to get the value in the cell. Get it directly from the table view instead.
Instead of this:
UITableViewCell *cell = [self tableView:[self tableView] cellForRowAtIndexPath:indexPath];
Do this:
UITableViewCell *cell = [[self tableView] cellForRowAtIndexPath:indexPath];
Doing it the way you are doing is essentially recreating the cell and so losing the value you have entered. The datasource method is only meant to be called by the table to work out what to display.
In your method to set the cell text, you alter the textField of the cell, but the string you grab to log/save to Core Data is from the textLabel. Is this an intentional discrepancy?

2 tableview on a single view

I need an example or explanations of how to populate 2 table views which are on the same view. I need to understand the "cellForRowAtIndexPath" method, could someone provide me an example on how should the code be?
I mean how to identify which goes which table view?
Thanks
Below is my cellForRowAtIndexPath method:
// Customize the appearance of table view cells.
- (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] autorelease];
}
// Configure the cell...
// Set up the cell
MyAppAppDelegate *appDelegate = (MyAppAppDelegate *)[[UIApplication sharedApplication] delegate];
if (tableView == radios_tv) { //radio_tv is an IBOutleet UITableView
sqlClass *aRadio = (sqlClass *)[appDelegate.array_radios objectAtIndex:indexPath.row];
[cell setText:aRadio.r_name];
return cell;
}
if (tableView == presets_tv) { //preset_tv is an IBOutlet UITableView
}
}
and hey vikingsegundo, now I need to delete a cell which is on my TableViewController class, how do I do this? I explain, here is my code:
- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
//Get the object to delete from the array.
Coffee *coffeeObj = [appDelegate.coffeeArray objectAtIndex:indexPath.row];
[appDelegate removeCoffee:coffeeObj];
//Delete the object from the table.
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
Since we put different controllers, how should we proceed for this line? Should I put the tableViewController instead of the "self"?
//Delete the object from the table.
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
IMO the cleanest solution would be to have one controller for each tableview.
radios_tv would call it own delegate's method, while presets_tv calls it own.
edit
if you use one controller for n tableview, you will have to use if-statemenst in many places,
in
– numberOfSectionsInTableView:
– tableView:numberOfRowsInSection:
– tableView:titleForHeaderInSection:
…
basically in all UITableViewDatasource-Protocol methods that you will need to implement.
So if you need to change something, you have to change it in many places.
If you use one controller class for one tableview, you won't have to check at all.
write a controller class for every tableview, make it conforming to the UITableViewDatasource protocol
implement the protocol methods you will need. at least
– numberOfSectionsInTableView:,
– tableView:numberOfRowsInSection:,
– tableView:cellForRowAtIndexPath:
call -setDataSource:for every tableview to an object of the right controller class
I think, it was shown in one of the WWDC 2010 videos. I am not sure, but I guess it was Session 116 - Model-View-Controller for iPhone OS.
edit
I wrote an example code: http://github.com/vikingosegundo/my-programming-examples
On one view controller if you have to use two tables then you can set IBOutlet to both tables or assigns different tag to them so when you use following cellForRowAtIndexPath you can differentiate in both tables as below
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCellStyle style =UITableViewCellStyleSubtitle;
static NSString *MyIdentifier = #"MyIdentifier";
DataListCell *cell = (DataListCell*)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
cell = [[DataListCell alloc] initWithStyle:style reuseIdentifier:MyIdentifier];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
if(tableView==tblLanguage)//tblLanguage IBOutlet for first table
{
if ((selectedIndexPath != nil) && (selectedIndexPath.row == indexPath.row))
{
UIImageView *imgView=[[UIImageView alloc]initWithFrame:CGRectMake(320-30, 9, 22, 15)];
imgView.image=[UIImage imageNamed:#"btn_Expand.png"];
[cell addSubview:imgView];
tblSongs.hidden=NO;
tblSongs.frame=CGRectMake(0,42, 320, ([arrSongListForSpecificLanguage count]*40));
[cell addSubview:tblSongs];
}
else
{
UIImageView *imgView=[[UIImageView alloc]initWithFrame:CGRectMake(320-30, 9, 16, 22)];
imgView.image=[UIImage imageNamed:#"btn_Collaps.png"];
[cell addSubview:imgView];
}
cell.lblCustomerName.textColor=[UIColor blackColor];
cell.lblCustomerName.font=[UIFont boldSystemFontOfSize:16];
//set the first label which is always a NamesArray object
[cell setcustomerName:[objAppDelegate.viewController.arrLanguage objectAtIndex:indexPath.row]];
}
else //for other table
{
ParseData *objParse;
objParse=[arrSongListForSpecificLanguage objectAtIndex:indexPath.row];
cell.lblCustomerName.textColor=[UIColor blackColor];
cell.lblCustomerName.frame=CGRectMake(cell.lblCustomerName.frame.origin.x, cell.lblCustomerName.frame.origin.y, 310, cell.lblCustomerName.frame.size.height);
//set the first label which is always a NamesArray object
[cell setcustomerName:objParse.track];
}
return cell;
}
}
You can also use tag for the same in which your if statement as below
if(tableView.tag==1)//tblLanguage tag=1
Similar if statement use for other delegate & datasource methods of table