I have a tableView with a few sections and I have it set for static cells instead of dynamic prototypes. The problem is that I can't set the detail text label of a static cell programmatically or at least I don't know how. Is it possible ? The only way I see of doing this is having dynamic prototypes which means I'm going to have to deal with setting up all the cell.textLabels in my dataSource and also all the sections and my segues will not work anymore. If anyone has ideas it would be great help. Thanks :)
Assuming that your UITableView is in a UITableViewController, here are 2 approaches that are useful:
Custom UITableViewCell: In the view controller class, declare a property for a label as: #property (strong) IBOutlet UILabel *labelInCell;
In the storyboard, drag a UILabel into the cell, select the controller's Connections Inspector, and connect the outlet of the property by dragging from the inspector to the UILabel object.
You can then assign the label text programmatically, for example, in viewDidLoad: of the controller class.
Standard datasource: Alternatively, you can implement just one method: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath in the view controller's datasource and set the detailTextLabel property there.
Related
I have a UITableViewController, designed entirely with Interface Builder. The UITableViewController is called DonationTableView. I am using Static cells and the UITableView has 6 sections. The reason I am using Static cells is because the content can be populated right from within the Interface Builder and because each cell contains:
1) A different size
2) A label with it's own text
3) A button
I can also use AutoLayout easily within Interface Builder to make sure this DonationTableViewController looks appropriate on all devices. I know I could use code, but I'm still a newbie here and I'm confident with Interface Builder.
I have a custom UITableViewCell class called DonationTableViewCell and I have assigned that to the UITableViewCell in Interface Builder. I am now trying to create an IBAction and IBOutlet for the UIButton in each cell, but with Assistant Editor up, it won't let me actually drag to create that IBAction in the way you usually do. If I change the UITableView to Dynamic, it then allows me to do that, but as mentioned above, I have a fully working UITableView with Static Cells and I just want to create a delegate method in the custom UITableViewCell class so that I can click the button and run an action.
So essentially, I want to be able to assign an IBAction to the UIButton in the UITableViewCell. How would I go about doing that?
Any thoughts would be appreciated.
Drag the button outlet or IBAction to your TableviewController
For use UiButtonin Tableview you need to follow this 2 Steps.
(1) Give UIButton Tag Inside Tableview.
Ex : Here your Button is identify with uniq tag .And also Give UIButton Method
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
cell.button.tag = indexPath.row;
[cell.button addTarget:self action:#selector(btn_Clicked_Method:)forControlEvents:UIControlEventTouchUpInside];
}
(2) In UIButton Method
- (IBAction)btn_Clicked_Method:(id)sender {
NSInteger tag= ((UIButton *)sender).tag
NSLog(#"Button row %ld",(long)tag);
}
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.
I have a custom static UITableViewCell that I want to look exactly the same as a right detail cell (UILabel on the left, UILabel on the right), except I want the right UILabel to be an editable UITextField. Since I want to use this cell in multiple view controllers in my storyboard, I decided the best option would be to create a MyEditableTableViewCell.xib file, along with corresponding *.h,m files. I have two public properties in MyEditableTableViewCell.h:
#property (weak, nonatomic) IBOutlet UILabel *textLabel;
#property (weak, nonatomic) IBOutlet UITextField *detailTextField;
These IBOutlets are connected to the UILabel and UITextField in the .xib file. In my storyboard, where I have a custom UITableViewController subclass, I change the class of the necessary UITableViewCell to MyEditableTableViewCell. I have a property in my view controller that is:
#property (weak, nonatomic) IBOutlet MyEditableTableViewCell *myCell;
However, when I run the app, the cell appears as simply a blank cell. Running some checks on it, I see that [myCell isKindOfClass:[MyEditableTableViewCell class]] returns true. However, the UITextField never seems to get instantiated. When I try to alter myCell.detailTextField.text, nothing happens, and myCell.detailTextField appears to be nil.
Any help would be appreciated!
How are you creating instances of MyEditableTableViewCell? My guess is you're doing [[MyEditableTableViewCell alloc] init] instead of loading them from the nib.
You don't need that property in your view controller. You need to register your cell nib with the table view using -[UITableView registerNib:forCellReuseIdentifier:]. Do that in your viewDidLoad. Then, when you send dequeueReusableCellWithIdentifier: to the table view, it will instantiate the nib, creating a MyEditableTableViewCell, and return it to you.
UPDATE
If you're laying out static cells in a storyboard, using a xib to lay out a cell is somewhat difficult. The simplest thing to do is simply lay out the cell's subviews in the storyboard. You can copy and paste the subviews to each cell if you have a few of the same type.
If you really want to use a xib, the easiest way is to structure your cell's view hierarchy like this:
MyEditableTableViewCell (in storyboard)
|
+- cell's content view (created automatically by UIKit)
|
+- UIView (top-level view of the xib)
|
+- UILabel (textLabel)
|
+- UITextField (detailTextField)
So you set the cell class in the storyboard to MyEditableTableViewCell. Then you create your xib. You set your xib File's Owner class to MyEditableTableViewCell. The xib does not contain a MyEditableTableViewCell. The top-level view of the xib is just a plain UIView, containing the subviews (the label and the text field).
In -[MyEditableTableViewCell initWithCoder:], after doing self = [super initWithCoder:aDecoder], instantiate the xib, passing self (the cell) as the xib file's owner. The cell can have outlets connected to the label and the text field in the xib.
After instantiating the xib, add the top-level view from the xib as a subview of self.contentView. If you're using auto layout, create constraints betwixt the top-level view and the content view. Otherwise, set the top-level view's frame to the content view's bounds and set the autoresizing mask to UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight.
Although a static table view will not fetch your cell from the nib, it will still call cellForRowAtIndexPath. There you can dequeue and return your fully unarchived custom cell. Properties on the custom cell that were set in IB, can be fetched by calling super on cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// get an empty cell with properties retained from IB
UITableViewCell *sup = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if ([sup isKindOfClass:[MyCustomCell class]]) {
// fetch a fully unarchived cell
MyCustomCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"foo" forIndexPath:indexPath];
// copy properties over...
[cell copyPropertiesFromCell:(MyCustomCell *)sup];
return cell;
}
return sup;
}
Depending on the situation, this might actually be easier than to mess with IB objects.
I'm a bit confused on how I go about changing the UITableViewCell. Is this correct?
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 95;
}
If I need to explain more I can. Sorry if this is a dumb question, I'm new to iOS dev.
That code is fine, it is probably just not being called. You need to properly set the delegate property of the table view for this method to be called.
or
Since your heights are all the same, you can take a shortcut and set the rowHeight property of your table view.
this delegate will change the height of the table view cell
first check you have declared table view delegate in .h file or not..
No need of declaring table view with property..
UITableView *tableView;
declare like this..
set your table's datasource and delegate to File's owner from .xib.
I'm trying to add a custom header to UITableView, that has some buttons and an UISearchBar.
The problem is, that when I try to use searchBar I get a message:
setting the first responder view of the table but we don't know its type (cell/header/footer)
Has anyone encounter such problem?
Are you adding to the table via:
[self.tableView addSubview:customView]
If so, that could be your error. Adding subviews to UITableView requires that you add them either as header, footer, or cell explicitly. Try:
self.tableView.tableHeaderView = customView
Just follow the simple steps here..
create a property for mySearchBar in your '.h' file and synthesize.
set its attributes in viewDidLoad/viewDidAppear method (or u can simply do it in the Interface Builder)
Use the following delegate method to set it as the header of your table view...
– (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return self.mySearchBar;
}