I've worked with custom cells before but I just wondered for adding a third label (nothing else!) is there a simpler solution? All I want to do is show the title, content and date. I've set the first two to the textLabels and detailTextLabels but I of course need a third for date.
So, is there a simpler solution without making a custom cell?
Thanks
See A Closer Look at Table-View Cells, section called Programmatically Adding Subviews to a Cell’s Content View.
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 220.0, 15.0)] autorelease];
mainLabel.tag = MAINLABEL_TAG;
mainLabel.font = [UIFont systemFontOfSize:14.0];
mainLabel.textAlignment = UITextAlignmentRight;
mainLabel.textColor = [UIColor blackColor];
[cell.contentView addSubview:mainLabel];
Try setting into cellForRowAtIndexPath (each time you create a new cell) modifying the textLabel and detailTextLabel Frame and adding to cell.contentView a new Label for the date...
But i think the correct way is to subclass the UItableViewCell class and create a custom cell
Related
is it possible to make a distance between cells like that in standard UITableView? There is no options to make separator bigger. Also this distance from right and left.
you can do this by set your cell background to whatever background you want (let's say gray in this case) and in the cell, add a white uiview with left, right, and bottom margin like this:
Then go to your table view, set the separator as none
and one last step, set the background of your table view to the same gray background as your cell.
Then you don't have to do anything particularly in your code besides simply initial your table cell based on the custom nib file (i assume you want to do this anyway).
If you prefer to construct your cell in codes, you can use the same logic.
in method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
cell.backgroundColor = [UIColor whiteColor];
// This will create a line of 3 pixels that will be separating the cells
UIView *separator = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,3)];
separator.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separator];
// and if you want the border do left and right add:
UIView *separatorRx = [[UIView alloc] initWithFrame:CGRectMake(318,0,2,cell.frame.size.height)];
separatorRx.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separatorRx];
UIView *separatorSx = [[UIView alloc] initWithFrame:CGRectMake(0,0,2,cell.frame.size.height)];
separatorSx.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separatorSx];
return cell;
}
One way would be to set the backgroundView of the UITableViewCell to an UIImageView containing this white box on that gray background
You have to make a subclass of UITableViewCell. In your own subclass you may make everything you dream about! So, you need to add UIView with whiteColor background and margins as subview on your custom UITableViewCell.
There is not padding option in UITableView. You can either add a UIView in your UITableViewCell which will contains all the cell subviews, and change it's frame to create a padding right in the cell.
I suggest you to use UICollectionView instead, you can easily set the space between cells using a layout. If the cell is smaller than the actual collection View, then it's automatically centered.
I have trouble with table view and its response because every cell has scrollView with 72 labels in it. I know that scrollView needs to load all elements first, and than load on screen, and because of that table view is slow, but is there a way maybe not to allocate and call initWithFrame method every time I create label? I tried to reuse label with different frame, but it is not working.
Here is code I need to optimize somehow to create labels faster.
int listSize = 36;
for(int i=0;i<listSize;i++){
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0+i*200, 0, 200, 80)];
label.text = #"HELLO";
label.textColor = [UIColor blackColor];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont fontWithName:#"ArialMT" size:18];
[scrolView addSubview:label];
UILabel *grayBorderInFront = [[UILabel alloc] initWithFrame:CGRectMake(2+i*200, 5, 1, scrolView.frame.size.height-10)];
grayBorderInFront.text = #"";
grayBorderInFront.backgroundColor = [UIColor lightGrayColor];
[scrolView addSubview:grayBorderInFront];
}
You can always have one TableView and eachCell has a horizontal CollectionView.
Set the scroll direction property to horizontal and use the UIViewCollectionFlowLayout
The CollectionView will guarantee that your labels (that are cells) are being reused and that you are doing an efficient job.
Few weeks ago I implemented EPG layout for iPhone app using collectionView with custom layout.
On the iPad app other developer implemented the EPG with scrollView with array of collectionView flow layout.
The custom layout work mach better.
You mentioned that you need iOS 5 hence you can try the following open source replacement to collection view:
https://github.com/steipete/PSTCollectionView
Save your labels in an array and then add them just to the view. Or you could even cache the whole scrollview.
Edit:
You keep a list of values that are updating. For all the labels created in the scrollview you set a tag label1.tag = 4; (starting from 1 instead of zero because 0 is the default one and other views have it as well).
Then, in your cellForViewAtIndexPath instead of creating a new label every time, you get the labels with [cell viewWithTag:] and you get a reference of the label. The only thing you have to do is to change the value of the label. You can also use the tag as index in the array:
int index = 3; // third label
[(UILabel*)[cell viewWithTag:index+1] setText:[myLabelsArray objectAtIndex:index]];
I have a UITableViewCell in which I would like to draw some lines (say a 2pt line at 1/3rd from top of the TableCell covering the whole width). The lines would always be in the same place within the tableview cell.
One straightforward solution is to just have a -drawRect method that will use CGContextStrokePath to draw the line. But that seems to be like an overkill since it would call drawRect everytime which is inefficient.
I would think that there would be a way to be able to cache it somehow, so that all tableview cells are created with the lines by default. One way I can think of is to create 2pt*2pt png file and add it to a UIImageView on top of the tableview cell. Any other ways?
Try this -
Add this code in your cellForRowAtIndexPath, just adjust y position og this image view-
UIImageView *seperatedImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 49, 320, 1)];
seperatedImageView.backgroundColor = [UIColor colorWithRed:201.0/255.0 green:250.0/255.0 blue:152.0/255.0 alpha:1.0];
[cellBackView addSubview:seperatedImageView];
Another option is, to add a UIView and set its background color. For example:
UIView *lineView = [[[UIView alloc] initWithFrame:CGRectMake(0,0,cell.contentView.bounds.size.width, 2)] autorelease];
lineView.backgroundColor = [UIColor grayColor];
[cell.contentView addSubview:lineView];
You can just add a UIView like a subView of your UITableViewCell.
I have a tableView with a textField and a textView in two cells. Thats it.
and I added them in tableView:cellForRowAtIndexPath:.
I can't edit the content!
Probably the touch is not passing through to the text field and the textView.
All the solutions are asking me to use a xib with a custom cell class.
So do I have to create two new classes for a two-row tableView ?
Cant I just get away by adding these as subviews to normal cell's contentView ?
Secondly, If using tableView for that kind of layout is overkill,
What is the alternatve where I need a textView below a textArea in a rectangular border with rounded corners and a separator between them with plain UIViews ?
You don't need to go as far as creating 2 new classes. Adding them will do just fine, maybe even keeping a reference in your controller.
Check for userInteractionEnabled on your UITableView, UITableViewCell, and your UITextField and UITextView. If you disable the user interaction for a view, every subview will have it's user interaction disabled as well. If you want to disable a row's selection, just set cell.selectionStyle = UITableViewCellSelectionStyleNone;
You don't need a xib to subclass UITableViewCell. In this case, adding to the content view should be fine, and a subclass would not be necessary. It does also sound like you do not need a table view. A reason you might want one is if you would ever need more of these cells, otherwise a regular view controller might be more appropriate and easier to implement.
I use Core Graphics to create rounded corners on UIView objects and even add shadow effects, but there is a bit of a learning curve. You could start by searching the Internet for UIView rounded corners.
Try to use this code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0){
UITextField *customField = [[UITextField alloc] initWithFrame:CGRectMake(60.0f, 10.0f, 400.0f, 60.0f)]
customField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
customField.delegate = self;
customField.adjustsFontSizeToFitWidth = NO;
customField.borderStyle = UITextBorderStyleNone;
customField.autocapitalizationType = UITextAutocapitalizationTypeNone;
customField.autocorrectionType = UITextAutocorrectionTypeNo;
customField.enablesReturnKeyAutomatically = YES;
customField.returnKeyType = UIReturnKeyDefault;
customField.keyboardType = UIKeyboardTypeDefault;
[cell addSubview:customField];
}
if (indexPath.row == 1){
UITextView *notes = [[UITextView alloc] init];
notes.editable = YES;
notes.font = DEFAULT_FONT(16);
notes.text = infoNotesStr.text;
notes.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
notes.backgroundColor = [UIColor blueColor];
notes.delegate = self;
CALayer *layers = notes.layer;
layers.cornerRadius = 10.0f;
[cell addSubview:notes];
}
}
Having a UITextField in a UITableViewCell
I'm making a fill-out form (First name, Middle Init, Last Name) using table views and want to embed text fields in some of my cells. I see a lot of examples on adding a UITextField inside a UITableViewCell, like the one above. However ALL of them have hard-coded values for the text field's frame, like this
UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
I want my text field to use the cell's frame or bounds.
To make things more interesting, my table view has four sections, and only section 1, which has 3 rows, will have text fields embedded.
To make things even more interesting, I use a popup controller to present my form.
So how can I embed my text field to fit properly inside my table view cells without using hard-coded values when setting its frame or bounds?
Thanks!
Autoresizing masks are your friend.
cell = [tableView dequeueReusableCellWithIdentifier:#"identifier"];
CGFloat optionalRightMargin = 10.0;
CGFloat optionalBottomMargin = 10.0;
UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, cell.contentView.frame.size.width - 110 - optionalRightMargin, cell.contentView.frame.size.height - 10 - optionalBottomMargin)];
playerTextField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:playerTextField];
If you want to ensure the UITextField fills the contentView of a cell then you do:
cell = [tableView dequeue....];
if (!cell) {
cell = ... // create cell
UITextField *textField = [[UITextField alloc] initWithFrame:cell.contentView.bounds];
textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[cell.contentView addSubview:textField];
}
Obviously this needs additional cell setup and something should be set to the text field's delegate. But this covers the basics of getting the text field to fill the cell's contentView. If the cell's size changes the text field will change along with it.
You could map it out using the storyboard editor by creating a custom nib that you then reference in cellForRowAtIndexPath
Assuming your targeting iOS5+, it's quite easy to do.
setup the nib in viewDidLoad with the following
[self.tableView registerNib:[UINib nibWithNibName:#"nibname" bundle:nil] forCellReuseIdentifier:<#(NSString *)#>]
load the nib in cellForRowAtIndexPath
CellClass *cell = [tableView dequeueReusableCellWithIdentifier:<#(NSString *)#>];
where CellClass is the class that you've created for the cell.
This approach allows a lot of flexibility to customize the cell as well as to create cell-specific methods. (say if you use more than one cell template w/in the tableView).