Best way to create custom UITableview section header in storyboard - ios

Current I am creating a prototype cell in storyboard and using this cell as a section header.
Inside tableView:viewForHeaderInSection: method, I am dequeuing the cell and returning it.
My section header cell has a UITextField and a UIButton in it.
When I tap on text field keyboard appears but as soon as focus is moved away from text field whole section header disappears.
This happens when I return the cell directly as section header view, but if I return a newly allocated UIView as section header view onto which cell is added as subview then everything works fine besides autoresizing masks.
Why header is disappearing?
I am not sure what could be the best thing todo here.
-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
static NSString *CellIdentifier = #"SectionHeader";
SettingsTableViewCell *sectionHeaderCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//return sectionHeaderCell; // returning cell directly, section header disappears when focus is moved away from text field.
UIView * headerView = [[UIView alloc] initWithFrame:sectionHeaderCell.frame];
[headerView addSubView:sectionHeaderCell];
return sectionHeaderCell;//header view never disappears, but auto resizing masks do not work. Need to know how to set autoresizing masks to headerView so that it resizes correctly.
}

Prototype cell table views only allow you to design cells in the storyboard editor, not section headers and footers. Your attempt to use a UITableViewCell as the section header is a clever hack, but it's just not supported by the classes involved—UITableViewCell is not designed to be used for anything other than a table view cell. It could do a lot worse than the view disappearing or not being laid out correctly; UIKit would be well within its rights to fail an assertion, delete all the app's data, revoke your developer certificate, or set your house on fire.
If you want your code to function properly, your choices are to either create your section headers in code or to put them in a separate XIB file. I know that's not what you want to do, but those are the options you have.

I had the same issue and the fix was to return the cell's contentView like:
-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
static NSString *CellIdentifier = #"SectionHeader";
SettingsTableViewCell *sectionHeaderCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
sectionHeaderCell.myPrettyLabel.text = #"Greetings";
sectionHeaderCell.contentView.backgroundColor = [UIColor whiteColor]; // don't leave this transparent
return sectionHeaderCell.contentView;
}
And you get the same autolayouted results as before, but without the disappearing.

I am sure you can use UITableViewCell as a section header, because UITableViewCell is subclass of UIView, so according to LSP
“objects in a program should be replaceable with instances of their
subtypes without altering the correctness of that program.”

In iOS 8, it's simple really. Just design your header the same way you design your cell. Everything is the same, you can put custom class and don't forget to add reuse identifier.
When it comes to use it in the code, just return that cell in tableView:viewForHeaderInSection method.
Don't forget to implement tableView:heightForHeaderInSection if you want to use fix height or tableView:estimatedHeightForHeaderInSection if the height depends on the cell intrinsic size.

Related

ios Tableview cell disappears when Selecting TextView

I have a tableview that has custom cells in it. The section header on the cell has a selectable textview.
When you double tap and select the textview then tap away from it... the cell literally disappears. But when I scroll completely so that the cell is out of visibility and go back then scroll back... the cell comes back.
Very confused as to why this is happening. Does anyone have any idea what would cause this issue???
Issue is specific to the Table view header section, if I have selectable textview in the other cells and tap away the cell doesn't disappear.
I think you are designed the View for header as a table view cell. The disappearing issue is may be due to two reasons
1.Please check the tableview and cell views scope you declared.If it is weak please make it as strong.
2.I will give u a sample code you need to declare in view for header delegate
If you returned cell instead of uiview it may happen.Please verify that one also.
static NSString *CellIdentifier = #"QuizCreation2HeaderTableViewCell";
QuizCreation2HeaderTableViewCell* sectionHeaderCell = (QuizCreation2HeaderTableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIView * headerView = [[UIView alloc] initWithFrame:sectionHeaderCell.frame];
[headerView addSubview:sectionHeaderCell];
return headerView;

UITableViewCell for headerview not loading subviews from storyboard

I have used a simple prototype cell from storyboard for adding header view to my table view. I added some labels in cell and give specific tag to every label, but while accessing it returns me nil value for [cell viewWithTag :] method.(I have not created a custom class for cell) I am using following method
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UITableViewCell * headerView = [tableView dequeueReusableCellWithIdentifier:#"HeaderView"];
UILabel * lblVenueName = (UILabel *)[headerView viewWithTag:100];
lblVenueName.text = #"Test Venue";
return headerView;
}
for above code the value for lblVenueName always return nil.
I ran into this problem in XCode 7.0 beta 5 (7A176x). I suppose it's a bug. I've checked in debugger and turns out that cell contentView does not have any subviews at runtime.
If you are designing for some specific screen size then this workaround may help you. Switch to the base values like this:
Then in attributes inspector check that both "installed" options are checked on all views that you need and their superviews (for example for all views in prototype cell, table view and it's superview):
After that you can return to your specific screen size and viewWithTag() will return correct values.
(id)dequeueReusableCellWithIdentifier:(NSString *)identifier
Return Value
A UITableViewCell object with the associated identifier or nil if no such object exists in the reusable-cell queue.
So I'm guessing that method returns nil for you :) Try a version that takes a indexPath :)

xcode document outline has extra content view

I am learning objective c and I'm following this tutorial here:
http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1
Whenever I create a table cell view, It creates an extra content view that makes it impossible to link my labels, images to the cell. How Can I delete the extra content view and link my objects?
Here is a screenshot showing what I mean...
Getting an Error with this code... use of undeclared identifier on cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MingleViewCell *cell = (MingleViewCell *)[[tableView dequeueReusableCellWithIdentifier:#"MingleViewCell"]];
LocalPerson *local = [self.people objectAtIndex:indexPath.row];
cell.nameLabel.text = local.name;
cell.aboutMeLabel.text = local.game;
return cell;
}
Relax. From the docs:
The content view of a UITableViewCell object is the default superview for content displayed by the cell. If you want to customize cells by simply adding additional views, you should add them to the content view so they will be positioned appropriately as the cell transitions into and out of editing mode.
This is how it's done, the content view should be there and you should be able to connect IBOutlets/IBActions normally by ctrl-dragging from your elements added to the cell in the storyboard into the custom cell class code.
you should not delete the content view which you are calling is extra. If you see UITableViewCell has a property contentView by default in which you add all the other content like UIButton, UILabel, etc. It's this contentView which is the main container.
So whenever you inherit any class from UITableViewCell, that class also has this contentView. So instead of deleting it you can use it as a container and add other elements.

UIButton in custom UITableViewCell stop working after rotation

Problem:
I used custom UITalbeViewCell that contains two buttons, they work fine in the portrait orientation. After the rotation, they all stop responding to the button touch up inside function. Some people having problems that their buttons couldn't drew correctly after rotation. Mine looked fine since the buttons are showing in the right places after rotation, but they do not respond to the button press anymore.
For this specific view in my app, I used a UIPageController to implement multi pages in a view, and for the view (name it EmbeddedView for now) embedded in the page's scroll controller, there is a UITableView that contains custom UITableViewCell. Custom table view cell only has a nib, the file's owner is EmbeddedView.
in EmbeddedView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
/*===== This is the most memory efficient way of creating table view cells =====*/
static NSString *CellIdentifier = #"CellIdentifier";
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[self customTableCellNib] instantiateWithOwner:self options:nil];
cell = [self customTableCell];
[self setCustomTableCell:nil];
}
}
What I tried:
I created another nib file for the custom table view cell and used it in -cellForRowAtIndexPath(), I checked the orientation and dynamically create the cell by using different nib, no luck.
I added [tableview reloadData] in -didRotateFromInterfaceOrientation(), didn't do anything.
Would someone point me to the right direction please? Any help is appreciated.
This is the table view Autosizing in IB:
It looks right but the buttons are not working
Update: I tried to specify different Autosizing masks in IB for the table view, and the results are showing below:
<1>
<2>
<3>
<4>
Have you checked how the superview is being resized?
Check if the superview has 'clip to bounds' checked. If it is not check it. That will make the view clip its contents so you see if it is resizing ok.
I'd say the superview is not sizing correctly and because of that the touch events are not well delivered also.
EDIT - So this was the tip that could let the OP reach the solution:
What I normally do in cases like of unexpected behavior in resizing and such is to change every view in the hierarchy to a different, well recognizable, color. Right now you have view A and view B with the same background color (or clear) and you don't see if view B is resizing well. Good luck.

Removing old data from reusable cell

I have a uitableview with each cell having a scroll view as the subview.
the scrollview has a bunch of images in it.
so when i change the data in the data source and after calling the reload table
the images doesn't change but when i remove the dequeue the new data is reloaded.
is there any method to remove the contents in the dequeue so that i don't get the old data
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"looser"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
scrollview=[[myscrollView alloc]initwitharray:imagearray];
[cell.contentView addSubview:scrollview];
}
}
A tableview works as follows:
It has room for a certain amount of cells on the screen, let's say 7 as an example. The tableview will ask you for the 7 cells of indexes 0 through 6.
If the top cell leaves the screen by scrolling, it will be placed in the reusable cell queue. There are now 6 cells on the tableview.
A new one comes up at the bottom now, the tableview asks for the cell at index 7. You call dequeueReusableCell, and you get the one that was at the top earlier.
The tableView has no idea what your cell is like, as it can be subclassed, so it will not make any changes to it. It is up to you to use your knowledge of how the tablecell is constructed to empty it, then fill it with the correct new data.
The reason tableview works like this is for performance. In stead of having maybe 100 views that would have to be checked (or mostly, ignored, which also costs time) for every scroll movement, it has a maximum of 7.
So in short, no. There are no default methods to remove data from reusable cells in UITableView, since UITableView can not and should not know what kind of cells they are. It is up to you to clear the cells when the tableview gives them to you.
Create a custom cell and it generates a method
- (void) prepareForReuse{}
Which do you cleanse all data from a cell and the output will be an empty cell.
No, not while the cell is in the cache. When you dequeue a reusable cell you should clear out the old data first before using it again.
Maybe you should just remove the stuff you don't want.

Resources