I need some help understanding what may cause my problem in my TableViewCell's content. In my app i use a forum. In the forum we use avatars to the comments/persons. Now I would like to give everyone with name "X" the same avatar. To do so I am trying with the code below but it does not work perfectly and I dont understand why? Sometimes the code bugs and gives for example a person with alias "Y" the "X" alias avatar?
1.First thing I do, is in the storyboard conntect the tag: tableView -> tableViewCell set the UIImageViews tag to 20.
2. Then i run the code below which works in other cases for Alias, Comments in the TableViewCells content.
static NSString *CellIdentifier = #"ForumthreadCell";
UITableViewCell *cell = [pTableView dequeueReusableCellWithIdentifier:CellIdentifier];
ForumPost *x [self.items objectAtIndex:indexPath.row];
UIImageView *pic = (UIImageView *) [cell viewWithTag: 20];
if ([x.alias isEqualsToString:#"X"]){
[pic setImage:[UIImage imagedNamed:#"some picture here.png"]];
}
Any help or suggestions are appreciated. Regards
This is because all the cells in UITableView are reused. That means that your first cell will be reused to load, let's say, your sixth cell. If you don't reload all the elements there and you have image in your first cell, that image will remain in the sixth cell. Another example you could use is to set if indexPath.row == 1 set some property of ForumPost to specific value(after initialization ForumPost *x) and you will have similar behaviour.
To have cells working properly, you need to manage all possible cases.
For instance, you have :
if ([x.alias isEqualsToString:#"X"]){
[pic setImage:[UIImage imagedNamed:#"some picture here.png"]];
}
But you need as well
else if ([x.alias isEqualsToString:#"Y"]){
[pic setImage:[UIImage imagedNamed:#"other pic.png"]];
}
and, if you have other starting names like a, b, c etc.:
else if ([x.alias isEqualsToString:#"Y"]){
[pic setImage:nil];
}
Related
This must be stupid question,
Some how I know the reason but difficult to find solution.
So any help will be welcome..
What I am having is, one UITableView with header.
Header contains the Question and UITableViewCell contains the options to question.
Each cell is having 3 controls,
2 Labels and 1 button.
1 label contain Option and other contains its answer.
To match the answer you have to select option from drop down, which is opened when button from that cell is clicked.
That drop down is again a UITableView.
Which options.
So that DropDownTableView is added over UITableViewCell.
but problem is that when I open drop down on that cell, the table goes beyond boundary of cell,
So DidSelectMethod of DropDown table is not getting called.
I can't increase the height of BaseTableVieCell, but I want to select option from DropDownTable.
What should I do.
I tried bringSubviewToFront, and also disabling the baseTableView when Button is clicked.
But didn't helped.
Is there any other way to achieve the task.
Thanks for help.
Here is the picture which will give detail idea.
I am not able to select option "A", "B" , "C" as they go out of boundary of cell.
Thanks in advance.
You just need to resize the cell whose button is clicked as follows:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
CGRect rect = cell.frame;
rect.size.height = 150.0;
ht = 150.0; // declared previously. you may check in the attached project
selected = indexPath.row;
[cell setFrame:rect];
[tableView beginUpdates];
[tableView endUpdates];
}
I have just given you an idea on how you will resize the cell. Here I have taken a static height(150.0). Instead of that you will have to give the height of your inner tableView that gets dropped down on UIButton click.
You can find demo project to change the cell height dynamically here.
Hope that helps.
I am totally new to iOS development and have been requested by my company to jump into some code written by another amateur that left us and fix it. The main view of this app is just a table view and we would like the user to be able to select one cell from the table, which would highlight it and set some other buttons on the page to do something to that particular cell.
Making the other buttons on the page works just fine, as long as I know what cell is selected, so I am not too worried about that. But the code this other guy wrote to select one cell at a time is atrocious, and the code I tried to replace his with was better, but still very buggy.
My code is this written below (sort of adopted from the old stuff that I don't completely understand). The issue with it is that the background turns black when the cell is clicked twice in a row or if you change views and come back to this table view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
for (int i = 0; i < [tableView numberOfRowsInSection:0]; i++) {
[tableView deselectRowAtIndexPath:currentSelection animated:true];
}
if(currentSelection.item == indexPath.item){
[tableView deselectRowAtIndexPath:currentSelection animated:true];
}
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
//highlight bg to light grey
cell.backgroundColor =[UIColor colorWithRed:200/255 green:200/255 blue:200/255 alpha:1.0f];
currentSelection = indexPath;
//code for other button functions
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
//set bg back to white
cell.backgroundColor =[UIColor colorWithRed:255/255 green:255/255 blue:255/255 alpha:1.0f];
noSelectedRows = true;
}
If that is too terrible too look at and try to fix, I was looking at a tutorial provided by Apple that I wanted to understand a little better anyway. The following code was found here: https://developer.apple.com/library/ios/documentation/userexperience/conceptual/tableview_iphone/ManageSelections/ManageSelections.html
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSInteger catIndex = [taskCategories indexOfObject:self.currentCategory];
if (catIndex == indexPath.row) {
return;
}
NSIndexPath *oldIndexPath = [NSIndexPath indexPathForRow:catIndex inSection:0];
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
if (newCell.accessoryType == UITableViewCellAccessoryNone) {
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
self.currentCategory = [taskCategories objectAtIndex:indexPath.row];
}
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:oldIndexPath];
if (oldCell.accessoryType == UITableViewCellAccessoryCheckmark) {
oldCell.accessoryType = UITableViewCellAccessoryNone;
}
}
The only things I need to know about that last code is where variables like self.currentCategory and taskCategories are coming from. As of now, there don't seem to be any similar variables in the code I am working with, so I would like to know what I have to point to or create.
This is also my first post on StackOverflow, so if I left out something important, please let me know.
The UITableView is a huge control, and it can be implemented in several ways. By your description, I think you using it with Static Grouped cells, in order to compose a form, right?
Actually selection display is handled automatically by the UITableView, so the code for didDeselecteRowAtIndex path which manually change cells background may be one source if the buggy behavior. Notice in the Apple Sample that they are using a similar logic to change the accessory view when cells are tapped, which need to be set manually.
If you're using the Storyboard and Template cells, you can set the "Selection" property on the cell to change the color when it is selected. Then you can remove the logic for changing cells backgrounds. I think it could be a good starting point....
You can right click on the variable and select Jump To Definition and it will show you where its declared.
As far as the rest of the code, what the other answers said is correct.
I suggest picking up a book on iOS development as well. Big Nerd Ranch's book is a great start.
One of your problems is, that
200/255 is 0
use 200/255.0f instead
Complementing Justin answers, here are some links. The iOS Apprentice Bundle is a great jumpstart material, that guides you through the creation of several Apps, pinpoint basics of iOS, such as the table view. I highly recommend!
http://www.raywenderlich.com/store/ios-apprentice
This series of videos also has a great introduction to Table Views, it will take less than a hour and will show the big picture on using UITableViews, this one is free:
https://www.youtube.com/watch?v=Rh-vfLXsTac
I am trying to create a project with a custom UITableViewCell. The custom cells never load, they're just blank. At this point in the project what I'm trying to do is placing a UITableViewCell in a .xib, designing it the way I want and specifying its reuse identifier along with tag IDs for the components so that I can use them in code later on.
I've googled a ton and found several tutorials that look like what I want to do, along with many SO questions that have answers that seem applicable. At this point it's probably just my head spinning with too many different angles and solutions.
This is my current attempt at trying to register the custom cell with my UITableView, yet when running this on a device the rows in the table view are entirely blank.
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"];
}
UILabel* l1 = (UILabel*)[cell viewWithTag:1];
UILabel* l2 = (UILabel*)[cell viewWithTag:2];
UILabel* l3 = (UILabel*)[cell viewWithTag:3];
l1.text = #"Foobar";
l2.text = #"Foobar";
l3.text = #"Foobar";
I'm pretty certain that I've hooked up all the properties and such correctly, but at this stage I need a fresh pair of eyes to point out the facepalm for me.
The interesting files are FilmerView.m/h/xib and the cell is in FilmerViewCell.xib. When running the app this TableView is in the second tab of the tab bar controller.
Project:
http://speedy.sh/WhhpP/test12.zip
I can't provide a full answer atm but look up the tableview method. registerNib:forCellReuseIdentifier:
Also, stop using that dequeue method. Use the one that includes the indexPath.
Then you don't have to check if the cell is nil afterwards.
EDIT
In viewDidLoad (or somewhere like that)...
UINib *cellNib = [UINib nibWithNibName:#"MyCustomCellXibFileName" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:cellNib forCellReuseIdentifier:#"CellIdentifier"];
Now in the table view datasource method...
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentifier" forIndexPath:indexPath];
// no need to check cell == nil.
// this method is guaranteed to return a non nil cell.
// if it doesn't then the program will crash telling you that you need to...
// register a class or nib (but we just did this in viewDidLoad) :D
// configure your cell here...
[self configureMyCell:(MyCustomCell *)cell atIndexPath:indexPath];
return cell;
}
- (void)configureMyCell:(MyCustomCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
cell.nameLabel.text = #"Hello, world";
}
Hope this helps.
Make sure that you have set datasource and delegate properties of your tableView.
Make sure that you have implemented (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section method and it returns a positive value (>0).
Evaluate the following:
Is the ReuseIdentifier set in the XIB. See Properties Tab in Interface Builder on the right when selecting the cell.
Are the AutoresizingMasks set properly for the labels to be visible?
WrapModes: Which did you select? When having wrapmode WrapWord, is the font size too large for the text to be moved in the next line becoming invisible?
Set the background color of the UITableViewCellss content view to something else than white or transparent, as well as the background colors of the labels to see if the cell is even there.
Manually call numberOfRowsInSection on your table, pass the proper NSIndexPath identifying the target section and see if its greater 0 to confirm that the TableView even attempts to load the data, thus, the cells. ( Alternatively set a breakpoint in the method or do a NSLog. )
Do a NSLog in cellForRowAtIndexPath to confirm that the cell returned is not nil and the method is even called!
I am trying to imitate the album page of iTunes using uitableviewcontroller, but then I think I might have been going in a wrong direction.
My plan is to do something in tableView: cellForRowAtIndexPath:. When indexPath.row == 0, I do the description of album (i.e. the upper part), else I do the description of songs (i.e. the lower part).
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.row == 0 ){
CGRect imageFrame = CGRectMake(5, 5, 69, 69);
UIImageView *coverFram = [[UIImageView alloc] initWithFrame:imageFrame];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:#"cover" ofType:#"jpg"];
coverFram.image = [[UIImage alloc] initWithContentsOfFile:imagePath];
[cell.contentView addSubview:coverFram];
}else{
NSInteger adjustedIndexPathRow = indexPath.row - 1;
cell.textLabel.text = [self.cellRow objectAtIndex:adjustedIndexPathRow];
}
return cell;
}
There are two places That I don't have simple idea to implement it:
Firstly, in the album page of iTunes, there is a segmented control (see the image). When I press other segment, say "review", the upper part remains there while the whole lower parts has been changed.
Secondly, I don't know how to close the gap show in the image (circle in red).
So, I think may be there are some other smarter(or easier) way to do it. Like, is it possible to divide the page into two part: then the do the upper part by a view; and do the lower part by a table view? (just my guess)
Please advice. Thank you.
Your assumption is perfectly right. That is the way to go in your case. Refer to the following image.
Construct the top part of the view containing the album cover, it's details and the segmented control. The bottom part of the view will be reserved for views which will be loaded by instantiating other view controllers based on selected segment.
You can remove this white space by two way,
in ios 7 set separatorInset in UITableView
1) set by Pragmatically
table.separatorInset=UIEdgeInsetsZero;
2) Or u can do this way
Your guess is right. The easier way(probably the right way) is to divide the entire view into two parts. The upper part consist of an image view, segmented control whatever else. and bottom part can have a table view. Now depending upon the selection of a segment in the segmented control you can easly reload the table view with appropraite content
I'm facing a paramount problem that led me almost to toss my computer out of the window.
I'm trying to create a button only on some cells, I don't have any problem about triggering the action, but when I scroll down the table and I come back to the first cells the button is created on other cells. In other words, if cells 1 and 3 are supposed to have the button, when the tableview is created they are the only ones having the button. When I scroll down and up again also cell 2, 3 and 4 have the button (there is not a specific rule). The button is also working perfectly but it is not supposed to be there!
static NSString *CellIdentifier = #"Cell";
OpinionCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell= [[OpinionCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
...some influent code.......
if(([[aComment objectForKey:#"TypeMsg"] intValue]==310)&&([[parentMessage objectForKey:#"TypeMsg"] intValue]==310)){
UIButton *_openReplyButton = [[UIButton alloc] initWithFrame:CGRectMake(280, 5, 20, 20)];
[_openReplyButton setImage:[UIImage imageNamed:#"reply_button.png"] forState:UIControlStateNormal];
[_openReplyButton addTarget:self action:#selector(addRowsForShowReply:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:_openReplyButton];
NSLog(#"%#", [aComment objectForKey:#"Message"]);
}
Thank you very much for your help!
This is a classic problem for UITableView. It took me ages to figure out the dequeuing and reusing process that the table view does. Here's what should fix it.
Move the code to initialize the button into the part that checks whether cell == nil. This is because you're not supposed to add subviews to cells that have just been dequeued, because you don't know whether that cell has already had the subview added to it. Also, you should either set a tag for the button or make it a property of the OpinionCell. That way you can access it later.
Then, if you have determined that the button should be visible, set cell.replyButton.hidden = NO or [cell viewWithTag:kMyButtonTag].hidden = NO. Very importantly, you should set it to be hidden in an else clause. Otherwise, the button will show on seemingly random cells.
Hope this helps!
You can use following code to remove the subviews from UITableViewCell right after when the
cell is dequeued or initialised as it will remove all its subviews or you can follow what dado728 has mentioned above.
[[cell subviews] performSelectorOnMainThread:#selector(removeFromSuperview) withObject:nil waitUntilDone:NO];