xcode document outline has extra content view - ios

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.

Related

Best way to create custom UITableview section header in storyboard

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.

iOS Container View in UITableViewCell

I'm trying to add another view controller inside a UITableView cell. The idea is that you tap the cell, and it expands to show more content--a messaging interface. It's important (I think) that this is controlled by a separate Messaging ViewController.
Expanding the cell and having views inside the cell expand with the proper constraints is actually very straightforward in Storyboards, so I tried to keep everything in storyboards by adding my new VC to the TableViewCell via a Container. That way I'd be able to add constraints on the container view, and pipe the content in from my Messaging VC.
Here's the error:
Illegal Configuration: Container Views cannot be placed in elements that are repeated at runtime.
Any way to get around this issue, or is there a way I can pipe the view from my viewcontroller into this tableviewcell and have it constrain to a configuration that I set in Storyboards? Thank you!
I had the same task and decided it this way:
Step 1. Create subclass MyCell: UITableViewCell.
Step 2. If you use Self-Sizing Cells, in InterfaceBuilder add UIView to MyCell, then add height constraint and constraints to all sides. This view needed for set height of cell.
If not, skip this step and use heightForRowAtIndexPath.
Step 3. In MyCell.h add outlet from view height constraint and controller property:
#interface MyCell: UITableViewCell
#property (weak, nonatomic) MessagingVC *controller;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *viewHeight;
#end
Step 4. In cellForRowAtIndexPath add code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell" forIndexPath:indexPath];
// adjust this for your structure
cell.controller = [[UIStoryboard storyboardWithName:#"MessagingVC" bundle:nil] instantiateInitialViewController];
[self addChildViewController:cell.controller];
[cell.contentView addSubview:cell.controller.view];
[cell.controller didMoveToParentViewController:self];
// if you use Self-Sizing Cells
cell.viewHeight.constant = 200; // set your constant or calculate it
return cell;
}
Step 5. Add didEndDisplayingCell method:
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if ([cell isKindOfClass:[MessagingVC class]])
[((MyCell*)cell).controller removeFromParentViewController];
}
Make your UITableViewController content as Static.
You can just drag Container View into UITableVeiw in the storyboard. For example, you can drag it before prototype cell, and you will see your container's view controller before your prototype cells. By the way you can drag any UI element to table view. I'm not sure, how to deal with autolayout in the combination table view + container view, maybe you need to manually calculate / set constraints at the runtime. Will update my answer when I'll find the right solution about autolayout.
Putting container views in table view cells is way too heavy. Table view cells should be lightweight so the user can scroll through them quickly. It's not necessary to put the entire view controller in each cell. The cell should just represent some of the data for that row.
When the user touches the cell you just use a normal segue to the messaging view controller. Its presentation will be automatic. Then create and specify an animationController to handle the transition to make it appear as though the message composition view was contained within the table view cell.

Cannot set properties on custom table view cell

I have a problem settings my view elements on a custom cell. The table cells appear in my tableView, but the properties do not set and thus only empty/blank cells appear.
The tableView is not a tableView controller, but only a tableView in a viewController.
I have the following files:
CustomCell.xib:
Here i use IB to build the custom cell by using a Table View Cell from object library with labels and images on. I set the Identifier as orderListCell. From this screen I ctrl+drag to create the outlets in customCell.h
CustomCell.h
Here I see all my IBOutlets as properties from above mentioned file
CustomCell.m
Here I leave as is
OrderListViewController.h
Here I import customCell.h and use protocols UITableViewDelegate, UITableViewDataSource
OrderListViewController.m
Here I set my tableView delegate and tableView dataSource to self. I also create an IBOutlet for my tableView from the Storyboard.
I use the following code to try and display my cells:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"orderListCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[CustomCell alloc] init];
}
cell.myLabel.text = #"aaaaaaaa"; //[[self.orders objectAtIndex:indexPath.row] objectForKey: #"tableNo"];
return cell;
}
I have simplified my code a bit to demonstrate that even setting the label to a simple string (#"aaaaaaaa") doesnt work. When I look at the objects in my debugger the cell does have all the properties from the IBOutlets and the cell does appear in my tableView, just the label.text = xxx does not seem to work.
I have looked at the following posts but either dont understand it properly or it does not work for me:
ios 7 customizing UITableViewCell's content view
Can't set properties in Custom UITableViewCell
Set label for a custom cell
Any help or advice would be greatly appreciated
cell = [[CustomCell alloc] init]; does not create your cell from the XIB, so none of the XIB content will be created.
Use registerNib:forCellReuseIdentifier: to register the XIB with the table view so that it will create your cell instances for you (you don't need to create instances yourself in cellForRowAtIndexPath).
If you don't want to do that, you can load your NIB explicitly with nibWithNibName:bundle: and instantiateWithOwner:options:, then get the cell instance from the list of returned views (which should only contain 1 item).

Adding buttons to custom Table View Cell under custom TableView Class

Edit: See my answer for a functioning app that somehow implemented what I was trying to do.
I've checked around for this and followed every available tutorial - this all seems pretty straightforward but my Storyboard & inspector simply will now allow me to do the following:
-- Add buttons to custom UITableViewButtons (using custom class 'Song Cell')
Every time I try to do so, it puts the button on a view which is above the table view. I've tried setting the cells to dynamic, static, basic, and every other toggle switch I could find.
I think its because I have a slightly awkward settup in terms of views, so I tried to set my TableView to a custom class as well. However, its not showing up in Storyboard's Class Inspector. Here is what I did, to set this Table View to a custom class, so no avail:
-- Create custom class inheriting from UITableViewController, called SongTableViewController
-- Set, in Storyboard, a table view controller's class to SongTableViewController
See this hierarchy:
// edit - Apparently I do not have 10 rep to post pics, so I'll just draw it myself:
▼ Voting View Controller - Current Songs
▼ View
▼ Table View // This is where I would like the custom class, SongTableViewController
> Song Cell
> Song Cell // These cells are where I would like to add the custom buttons
> Song Cell
> Constraints
> Label - 00:00
> Label - Voting will reset in:
Navigation Item - Current Songs
First Responder
Exit
When I select the Table View and go to the inspector to change its class, there is no option except for UITableView. Trying to hardcode this and hitting 'return' also does nothing.
Is my inability to add buttons to these cells due to the structure of
my views? Or something else?
Maybe you should create a xib with your custom cell. For exemple, the class "CustomeCell" with the xib "CustomeCell.xib".
You put some objects on your cell via xib file and in your class with your UITableView, do something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
// configure cell
return cell;
}
Don't forget to link you datasource and delegate for your TableView in the xib file AND add the delegates in your UITableView class :)
Storyboards are usefull but sometimes, the good way is to use xib files :)
EDIT: You can read this tutorial, it's a very good example how to manage custom cell / tableview with xib files: http://www.appcoda.com/customize-table-view-cells-for-uitableview/
Hope it help you :)
You probably don't want to change the class of the table view. It sounds like what you really want to do is change the class of one (or more) of the cell prototypes. In the storyboard select one of the cells and change its class to your song cell class.
Here is a description of what was going on, and an example of how to impliment this:
You have one UIViewController subclass, and add
the table view to it by dragging and dropping in the storyboard.
You then have a bit of extra work to do to fill the gap between a
table view controller and a plain view controller - declare that you
conform to the datasource and delegate protocols, create an outlet for
the table view, connect the outlet to the table view and connect the
table view's delegate and datasource outlets to your VC.
Implement the three datasource methods (number of sections, number of
rows and cellForRow...) and you're done.
Link to Prototype

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.

Resources