Why can't I define IBOutlets when using custom "prototype tableviewcells" - objective-c

I have my own table view cell which is defined in my storyboard. I have also defined a custom UITableViewCell class for this special cell. So when I want to create an Outlet for my custom prototype cell I get an error that the Outlet cant be created.
Since this is not possible I have to do some ugly workarounds and use the tags in IB to reference the individual labels and buttons later on in my code.
I don't really see why this is not possible and I wonder if working with tags and [myCell viewWithTag:] is the best possible way to go here?

Because the outlet is a one-to-one connection between your controller and a specific item within the view. In the case of a prototype cell, it is simply a description of a cell that can have an arbitrary number of different items (i.e. rows in your table view). How would the controller know which item you are referring to (e.g. row 5 or 500)? That is why you are receiving the error message.
Lucas provided one method to refer to your connection via tags which works perfectly well.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentInIB"];
UIImageView *img = (UIImageView*) [cell.contentView viewWithTag:1];
//img.image = ...
//Access you prototype cell here to alter its style, example:
[[cell layer] setCornerRadius:10];
[cell setClipsToBounds:YES];
return cell;}

I assume you are using dynamic prototypes - in the attribute inspector of the tableview in the storyboard there is an option to select "static cells" or "dynamic prototypes". You can do what you are trying to do if you select "static cells" as there is only one cell in your tableview at run time for each cell in the storyboard. Using this approach you will only be able to use the cells you create in storyboard i.e. you will not be able to select the number of cells in your code.

Related

UITableViewCell as Header or Footer View

I know about UITableView reusable header and footer view
but in my case, i have UITableView Cells, which i need to place also in section headers and also in normal rows
if i use
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
MyCell * cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
// ...
return cell;
}
How does it work out with the reusing? (is the message to be available for reuse even than passed), or does this disable the cell reuse
The cells get dealloc'ed when they go off-screen. So they don't get reused. An easy way to verify this is to subclass UITableViewCell with the following
- (void)dealloc
{
NSLog(#"I got dealloc'ed");
}
and observe the console output as you scroll.
These has always worked fine. You first should create a prototype with that name, or register a custom nib with your custom section identifier. HOWEVER , I noticed this breaks in iOS 7 when you add new sections to the table dynamically. Reverting to a plain non-reusing UIView works. Really a shame!

How do I re-use my custom UITableViewCell in various UITableView?

I have three separate "UIViewControllers" in my app. Each has UITableView attached to it.
First UITableView displays just a single table of rows of data (news items).
Second UITableView displays a search view, which has a few sections where users type in different search criteria.
Third UITableView displays the article details.
In each of the UITableView, there is a button.
First UITableView has "Load more articles" button.
Second UITableView has "Search" button
Third UITableView has "Visit article page" button.
Since all three views are UITables, I created a custom UITableCellView and added to each of the UITableViews. Here's an example of my "ButtonCell" in the 2nd UITableView
ButtonCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ButtonCell"];
NSString *cellText = #"Search";
[[cell buttonLabel] setText:cellText];
return cell;
This works well - exactly how I want it.
Now I added the same "ButtonCell" to the first and third UITableView, but a few strange things happened.
The background color of the ButtonCell is not correct - in the ButtonCell ".xib" file, I set it to a blue-ish color. This works well for the 2nd UITableView, but for others, it's just "white".
The ButtonCell doesn't have "rounded corners" anymore.
Any ideas on how to properly "re-use" my custom button cell in any UITableViews?
It sounds like your second table is grouped, and the other two plain (you get rounded corners with a grouped table view style). Setting the color of custom cells in IB for plain tables doesn't work. You should set the color of your cells in the tableView:willDisplayCell:forRowAtIndexPath: delegate method:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.backgroundColor = [UIColor colorWithRed:.67 green:.93 blue:1 alpha:1];
}

access text in cell.textLabel.text

This seems like a simple thing but I'm stuck.
In my storyboard, I have a cell with text in it's label (using Static Cells). In didSelectRowAtIndexPath, I'm trying to access the cell's textLabel's text. Here's my code, with NSLogging:
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.textLabel.text) {
NSLog(#"cell.textLabel.text = %#",cell.textLabel.text);
} else {
NSLog(#"!cell.textLabel.text");
}
NSLog(#"just for fun: cell.textLabel.text = %#", cell.textLabel.text);
The if statement always returns "!cell.textLabel.text" and the last NSLog is always (null) although the storyboard's cell has text in it.
Is cell.textLabel not correct? Should I be looking at another subview of UITableViewCell?
The default cell style of table cells in the Storyboard are of type 'Custom'. Which gives you a blank cell where you can add other types of controls to it.
If you dragged a label onto the cell and changed its text, then you are likely using a Custom style of UITableViewCell.
The property textLabel is only available on cells of types other than Custom, such as Basic, or Detailed.
Therefore you should first check out if these styles meet your requirements and use them instead.
If you really do require a Custom type of cell, you will need to make a subclass of UITableViewCell and create outlets to access your label.

Preventing blue background on selecting a cell

I want to remove the selection color that appears when I touch a cell in my tableview.
In IB there is a "shows selection" checkbox that does nothing and it seems from what I can gather that it is just a bug in IB.
But then there is the
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
that I can set to each cell.
This also does nothing, so this is where I am stuck, all documentation say that if I set this property it should not appear but it does.
I push another UIViewController on a UINavigationController, and when I go back to the view in question, the blue background on the cell is stuck until I touch another one.
The only thing special is that I instantiate this UITableViewController with the help of storyboard and I use prototype cells. Then I put it inside a UIScrollView to have horizontal paging between multiple UITableViewControllers. There is no way to access the navigation controller when I do this so I pass the UINavigationController along to the UITableView.
Sorry that I can't make the keywords appear as code, it says I should press the tab key then type a $ but that moves my cursor to tags.
You might try to set the selectedBackgroundView of your cell like this :
customCell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background.png"]];
In the delegate method cellForRowAtIndexPath
From code you can use (for example for grey):
cell.selectionStyle = UITableViewCellSelectionStyleGray;
And put this at:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
In your ViewController.
The solution was to set the style on the prototype cell in IB. Many things are wierd about prototype cells.

Search result of UISearchDisplayController has other cell layout and behaviour than searched table

I am using storyboarding. I have an UITableView with one prototype cell. This cell is of style "subtitle". I have added a segue from the cell to the detailed view. So when the user taps a cell it will open the corresponding editor... That all works great.
Now I added a UISearchDisplayController an a UISearchBar, implemented the delegates. That works very well.
But in the search result table the cells are of style "default" and are not tapable. What do I have to do to get a result table looking and behaving like the "unsearched" table?
I would like to contribute for answer #1 this is what I did and it worked for me
in the method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
instead of assigning the cell from the parameter tableView
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
assign it directly from the TableView on the view so you have to replace this
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
with this
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Found the problem...
The method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
pulled the cell from the tableView, which is in the result case not the tableView from the storyboard but the resultTableView from the SearchDisplayController.
I now get the cell to display in both cases from the table view in the storyboard and now it works.
I've been using ios 7.0 and Xcode 5.0. I found that search display controller is using the same tableview layout as the delegate view controller. All you have to do is judge if the current tableview is the delegate view controller's tableview, or the search display controller's tableview. But remember to add the sentence
tableView.rowHeight = self.tableView.rowHeight;
in the following code snippet:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (tableView == self.searchDisplayController.searchResultsTableView)
{
tableView.rowHeight = self.tableView.rowHeight;//very important!
return [self.searchResults count];
}
else
{
...
return ...;
}
}
if you forget to implement that sentence, then the row of the table view of search display is only as high as a default row, which makes you think it doesn't look like the "unsearched" table.
There is a possible answer to this here. It may not work entirely for you, but as I explained, the UISearchDisplayController creates the table view.
Check the documentation and you can get a better understanding of it, but it states:
You initialize a search display controller with a search bar and a
view controller responsible for managing the original content to be
searched. When the user starts a search, the search display controller
is responsible for superimposing the search interface over the
original view controller’s view and showing the search results. The
results are displayed in a table view that’s created by the search
display controller. In addition to the original view controller, there
are logically four other roles. These are typically all played by the
same object, often the original view controller itself.
In my case UISearchDisplayController was using right cell type (custom) but height of cell was wrong so I had to use
(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
method to fix it.