Have have created a child of UITableViewCell, MenuItem which contains functionality for my custom table cell. I have also created a xib-file with a custom cell and set the UITableViewCell in the xib-file to have the class MenuItem. The name of the xib-file is MenuItem as well. In my UITableViewController class I'm doing this in ViewDidLoad:
UINib *menuItems = [UINib nibWithNibName:#"MenuItem" bundle:nil];
[[self tableView] registerNib:menuItems forCellReuseIdentifier:#"MenuItem"];
But the background color used in the xib-file isn't used in the cells the table displays. If I add a new label, it shows up, but the background color is just plain white. Does anyone know why?
EDIT: I do use [tableView dequeueReusableCellWithIdentifier:#"MenuItem"]; in cellForRowAtIndexPath.
Thanks to Sudha for links to the answer.
It turns out you can't set the background color in the xib-file. You have to do it in the willDisplayCell of the delegate. Read http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html, outlined box close to the top.
Related
I have custom cell created with nib. In the table view I am using the method -(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath to set the height of cell
Everything works fine.
But the problem is that I also want to change the size of UIlabel which is added as subview in nib of cell.
How do I do that?
Which metod to override in customcell class ?
The method you are looking for is:
-(void)layoutSubviews
{
[super layoutSubview];
//Do your magic
}
layoutSubviews is call after the cell is created and whenever the device orientation changes, to allow you to resize and/or move the subviews (plus make any other minor adjustments) to compensate for differences between the orientations, but in this case you can also use it to redraw your subviews.
As you have UILabel in your custom cell class, make a function in that class that take frame you want to set as parameter. Set frame of label in that function. You need to call this function from your cellForRowAtIndexPath method before returning the cell.
If you are reusing your custom cell you should call method only when the (cell == nil)
Also if you can add some code in your question that would be helpful and you can get more precise answer.
You need to treat your custom cell in the same way you would treat a normal view or view controller class with a xib. i.e. You need to create IBOutlets for the controls in you custom cell and during creation of the cell you can access the controls quite easily.
myCell.myCustomUILabel.text = #"blah"
There are some gotchas when using custom cells in a xib and onnecting up the IBOutlets. This SO answer (of mine) explains how to create and link up IBOutlets of a custom cell.
I want to add a UIPickerView to a UITableViewCell. Right now I am just getting a black window. Can someone also explain me the concept of subclassing UI objects to a cell ie:when do we make our cell as the delegate and the datasource delegate? Thanks
EDIT: Here is the code of what i am doing right now
case 1: {
cell = [tableView dequeueReusableCellWithIdentifier:#"groups"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"groups"];
}
/*NSString *myGroupDetail = [_groupArray objectAtIndex:indexPath.row];
NSLog(#"the group detail label is %#",myGroupDetail);
cell.textLabel.text = myGroupDetail;
*/
[cell addSubview:_groupPicker];
break;
}
The groups is the section in which I want the picker view, I am getting that data from an array.
you would have to allocate and initialize a pickerview in your cellForRow method of the tableviewdelegate. ill sketch it for you =) how to initialize a cell itself should not be hard to find out if you google a bit ;-)
...(tableView *)... cellForRowAtIndexPath... {
if(indexPath.row == pickerRow){
UIPickerView *pickerView = [[UIPickerView alloc]init];
cell = ... // alloc and initialize a cell
cell addSubview:pickerView];
}
else{ // your other cells }
return cell;
}
UPDATE: im currently having trouble with git, so i uploaded a sample project to my private server: UITablePicker example
github: https://github.com/sebamisc/UItableViewWithPicker
yu can modify and use the code however you want =)
sebastian
Well, I never did exactly that.
Does it have to be in a cell or could you use the table's header or footer view for that? (I would not suggest a section header/footer view.)
Assuming it is within a UITableViewCell.
Yes, I personally would subclass UITableViewCell. Did that a lot. In that case you cell object could be the data source delegate of the picker. For doing so your subclass of UITableViewCell (let's assume you name it MyTableViewCell) needs to fulfil the related protocol. You add that UIPickerView programmatically within the init Method (initWithStyle) of MyTableViewCell. For the layout within the table cell, you should overwrite the method layoutSubviews. If your app can be rotated to landscape and portrait orientations and/or if your app is designed to run on iPad as well, then this method should dynamically consider the table's bounds. (Screen or windwo bounds are often used hiere but that is not save when the table is displayed within a split master view or a popup view on iPads.)
Strictly spoken your MyTableViewCell should not be the data source delegate, simply because it is a view element and view objects are not supposed to manage any business logic within an MVC design pattern. Smarter would be the implementation of some dedicated view controller for your table view cell hat fulfills the protocol and is assigned as the delegate. However, both would work. In the event that it is the only picker view within your sell, then you could easily use your UITableViewController subclass even without tagging the UIPickerView.
An alternative to subclassing a UITableViewCell is to create the UIPickerView within the cellForRowAtIndexPath method of your tableViewController. That is fine for singe-orientation apps. However, you may setup it in a way that it re-arranges its the UIPickerView automatically.
In any case you should overwrite the heightForRowAtIndexPath method of UITableViewController when your table views do not have the same hight any more. If all of them still have the same height, then you can simply set the rowHeight property of your UITableView.
In my Universal IOS4 app, I have a UITableview in my xib and I control it with my UITableViewController. As you know tableview by default covers all the area in window left from the navigation bar on top and the toolbar at the bottom.
What I want is to add another UIComponent(probably a big UILabel) just under the navigation bar and place the scrollable tableview just under that UILabel, so UIlabel is not scrollable but only the table is
How can I do and control that?
Thanks
Never mind: I think this will scroll with the table.
You can set the section header to the view below. This may work if you only have one section. Best solution would be to change to a UIViewController.
Programmatically add a header to the table
UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0,0,320,30)] autorelease];
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0,0,50,30)] autorelease];
label.text = "Hello";
[view addSubview:label];
self.tableView.tableHeaderView = view;
I would suggest not to go with using UITableViewCOntroller at all. If you use UITableVIewCOntroller to ease the way you use Delegates and Data Sources, then you will have to face this kind of Customization problems.
You will have below problems if you UITableViewController:
can not set the background to a custom UIImage. You can only set the UITableView’s BG property. If you use a Custom VC and add a UITableView to it. you can entirely customize what to keep on top of the View, widtt and height of your table view.
You can not have a static Header view in your View at all. Because if you use UITableVC, you can only have the default header that you can create using Table View's data source methods. But if you use a customized VC and add a TableView to it, you can add your own customized header or controls as a header.
only advantage you will have if you use a UITableViewController is that if you have UITextFields in your Table View, UITableViewCOntroller will automatically scroll the hidden text field to above the Keypad if you start editing one.
I would not suggest you to add anything to UIWIndow, as only the first added view to window will get the rotation events
http://developer.apple.com/library/ios/#qa/qa1688/_index.html
One simple idea is to have another UIViewController (let's call this a_viewController) and set the tableview (let's call it a_tableView) and the label (samewise, a_label) as its subviews.
[a_viewController.view addSubview:a_tableView]
[a_viewController.view addSubview:a_label];
TableView header may not work in case you want the label to stay as you scroll.
But if you have only one section in your tableview, section header may become a handy option.
Can i make a table's tableHeaderView position fixed as I scroll?
One of the way is you can add on UIWindow. But make sure you handle it properly while navigating views... Following is the way...
UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window)
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
[[[window subviews] objectAtIndex:0] addSubview:myView];
Create your UILabel instance (myView) and add it as subview in UIWindow...
I'm trying to determine whether a UITableViewCell subclass is in edit mode from a user's swipe (in which case I don't need to indent my subviews) or from the user pressing the "Edit" button associated with the UITableViewController. (In which case I do.)
I know it's possible from a cell's perspective, since the self.textLabel view automatically indents properly. I have tried:
-(void)layoutSubviews {
[super layoutSubviews];
CGRect labelFrame = self.textLabel.frame;
labelFrame.origin.x += 5;
myCustomUILabel.frame = labelFrame;
}
But my custom label does not properly indent. (Though the self.textLabel view does?)
I would like to avoid the following:
Providing the cells with a reference to the parent table.
Overriding methods in the UITableViewController class to let the cells know whether they are being edited individually or the entire table is editing.
You can override willTransitionToState: in your UITableViewCell subclass. When the "Edit" button is pressed the state will be UITableViewCellStateShowingEditControlMask(=1) and when swiping it will be UITableViewCellStateShowingDeleteConfirmationMask(=2).
You should not be doing the indentation manually. The UITableViewCell will do it for you!
All you have to do is make sure that you add your subviews to 'contentView' of the UITableViewCell. This is the reason why self.textLabel indents properly as you have identified.
Look at the documentation of contentView property for a UITableViewCell:
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.
I have a TableViewController and would like to have a static picture as a background, which doesn't scroll along.
The way that everyone recommends using
[UIColor colorWithPatternImage:[UIImage imageNamed:#"backgroundPattern.png"]]
doesn't work as it will
1.) move along and
2.) put the background pattern in every cell
I know how to do it in a XIB file (namely adding another layer underneath the TableView) but how do I do it programmatically from the TableViewController?
[myTblViewController.view insertSubview:myImageView belowSubview:myTblViewController.tableView];
That should work.
If it turns out that tableView is not a direct subview of the table view controller's main view, you can try:
[[myTblViewController.tableView superview] insertSubview:myImageView belowSubview:myTblViewController.tableView]; //Edited superview should be all lower case