I want to move the position of the title textview in my cell prototype. When I select the "Title" I cannot adjust the X,Y coordinates or even the Width and Height. Are we not allowed to customize this part of the cell.
When I tried to do this in code it said I was not allowed to access the current parameter. How do I move the location of this title and subtitle. I want to move it to the top of the cell and have my colored views below. Thanks in advance, still somewhat new to Xcode.
cell.textLabel.frame.origin.x = 30; //not allowed to access
you cannot access to the x position, but you can put the whole frame easily.
Here and example all by code, I think It's your best option:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *reuseIdentifier = #"reuseIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
cell.textLabel.frame = CGRectMake(0, 0, cell.frame.size.width, 30);
cell.textLabel.backgroundColor = [UIColor greenColor];
}
// Configure your cell...
return cell;
}
Here using Story cell, I think is worse because more work.(It didn't take advantage for the reuse technology at all).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"storyIdentifier" forIndexPath:indexPath];
cell.textLabel.frame = CGRectMake(0, 0, cell.frame.size.width, 30);
cell.textLabel.backgroundColor = [UIColor greenColor];
// Configure your cell...
return cell;
}
Related
I am creating a tableView with 4 cells. And the cells must be divided into various size depending on the orientation of the device.
1st column and 2nd column will have the same width, while 3rd column will be the largest of them all and the 4th column will be a smaller than the 3rd column but not smaller than the 1st nor 2nd.
Is there a way to do it dynamically?
Here is the template
I am having trouble in computing the width, here's what I have so far. I haven't created l2,l3 and l4 yet cause I am having a hard time in computing the width of it
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cells" forIndexPath:indexPath];
UIInterfaceOrientation newOrientation = [UIApplication sharedApplication].statusBarOrientation;
UILabel *typeLabel = [[UILabel alloc] init];
if (cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cells"];
}
if(newOrientation == UIInterfaceOrientationLandscapeLeft || newOrientation == UIInterfaceOrientationLandscapeRight)
{
l1 = [[UILabel alloc] initWithFrame:CGRectMake((self.tableView.bounds.size.width/15+20), 50, self.tableView.bounds.size.width/12, 21)];
}
else
{
l1 = [[UILabel alloc] initWithFrame:CGRectMake((self.tableView.bounds.size.width/15+50), 50, self.tableView.bounds.size.width/12, 21)];
}
[cell.contentView l1];
[cell.contentView l2];
[cell.contentView l3];
[cell.contentView l4];
return cell;
}
Create a custom TableView Cell named "CustomCell". You can create it using new File with xib option.
CustomCell.h
#interface CustomCell : UITableViewCell
#end
CustomCell.m
#implementation MessagesTableViewCell
//perform your custom implementation here.
#end
CustomCell.xib
Adjust the labels in the cell in the user interface using auto-layout. You can add 4 labels as you need with first 2 labels having a constant width and last one with the width you want and let the center(3rd) label stretch across 2nd label and 4th label. It will help you manage the UI in much easier way. Auto-Layout is a feature which helps to build content for different sizes. You can find dynamic table view cell using auto layout at https://www.sitepoint.com/self-sizing-cells-uitableview-auto-layout/
Using it in your TableView Class
static NSString *cellIdentifier = #"CustomCell";
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
return cell;
}
I hope this helps you.
Updated code implementation with programmatic computation and Orientation change
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
/////////////////////////Programatic Implementation///////////////////////////////////
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell==nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) {
//orientation is Portrait
long widthForL1L2 = tableView.frame.size.width * .10;
long widthForL3 = tableView.frame.size.width * .60;
long widthForL4 = tableView.frame.size.width * .20;
UILabel *l1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, widthForL1L2, cell.frame.size.height)];
l1.backgroundColor = [UIColor redColor];
[cell addSubview:l1];
UILabel *l2 = [[UILabel alloc] initWithFrame:CGRectMake(widthForL1L2, 0, widthForL1L2, cell.frame.size.height)];
l2.backgroundColor = [UIColor yellowColor];
[cell addSubview:l2];
UILabel *l3 = [[UILabel alloc] initWithFrame:CGRectMake(l2.frame.origin.x+widthForL1L2, 0, widthForL3, cell.frame.size.height)];
l3.backgroundColor = [UIColor greenColor];
[cell addSubview:l3];
UILabel *l4 = [[UILabel alloc]initWithFrame:CGRectMake(l3.frame.origin.x+widthForL3, 0, widthForL4,cell.frame.size.height)];
l4.backgroundColor = [UIColor blueColor];
[cell addSubview:l4];
}else{
//orientation is Landscape
//perform the same calculation as above or modify it according to your needs in landscape orientation.
}
return cell;
}
Do not forget to include this function of orientation change. This function calls table reload when phone orientation changes.
//Available iOS version >=8.0
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
//Reload the tableview on orientation change, to match the new width of the table.
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
[self.tableView reloadData];
} completion:nil];
}
I want to put two text label in one cell. I used the Json to show data from server and I want to show first title then the text below on( not subtitle).
this is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
City * cityObject;
cityObject = [ citiesArry objectAtIndex:indexPath.row];
cell.textLabel.text = cityObject.cityState;
cell.textLabel.text = cityObject.cityPopulation;
}
Is the cell designed in a storyboard or NIB? If so you can either make that cell style to be subtitle or add the two labels there to the contentView. Assign them unique tags so you can query them in the cellForRowAtIndexPath: method and set their text.
If you do not have storyboards or NIB designing the cell then something like the following should work.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]
}
// Configure the cell...
City * cityObject;
cityObject = [ citiesArry objectAtIndex:indexPath.row];
cell.textLabel.text = cityObject.cityState;
cell.detailTextLabel.text = cityObject.cityPopulation;
}
Nice and simple for this one..
Just create two labels and add them to the cell view. Eg..
UILabel* label1 = [[UILabel alloc] initWithFrame:(CGRectMake(0, 0, 10, 50))];
label1.text = cithObject.cityState;
[cell addSubview:label1];
UILabel* label2 = [[UILabel alloc] initWithFrame:(CGRectMake(0, 0, 10, 50))];
label2.text = cityObject.cityPopulation;
[cell addSubview:label2];
you can add this code in your - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath:
cell.detailTextLabel.text = cityObject.cityPopulation;
for detail ,please read
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7
I have an image size : CGRectMake(100,70,50,50) inside cellForRowAtIndexPath. I need to change the frame size image when the cells is odd
Code is:
if(indexPath.row %2)
{
CGRectMake(200,70,50,50)
}
else
{
CGRectMake(100,70,50,50)
}
In the first time when I load TableView, it's work ok, but when I scroll again and again, the frame size image display is in the wrong position. It changes very funny, I don't know why.
Can you help me
Thanks a lot.
You have set set the frame on your UIImageView subview:
if(indexPath.row %2) {
cell.yourImageView.frame = CGRectMake(200,70,50,50)
} else {
cell.yourImageView.frame = CGRectMake(100,70,50,50)
}
You can do it following way.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UIImageView * imageView;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
if(indexpath.row%2 == 0)
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(200, 70, 50, 50)];
else
{
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 70, 50, 50)];
[cell.contentView addSubview:imageView];
imageView.tag=11;
[imageView release];
}
}
else
{
imageView = (UIImageView*)[cell.contentView viewWithTag:11];
}
// here are couple of other statements
...............
}
Personally, I would create a custom table cell and do something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ImageCell";
ImageCell *cell = (ImageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
[cell configureWithRow:indexPath.row];
}
Then in your custom table cell, create an IBOutlet for your resizable image view and add a method:
-(void)configureWithRow:(NSInteger)row
{
if(indexPath.row %2)
{
self.resizableImageView.frame = CGRectMake(200,70,50,50)
}
else
{
cell.resizableImageView.frame = CGRectMake(100,70,50,50)
}
}
This does a couple of things
You don't have to check for a nil cell because you are guaranteed to get a cell back dequeueReusableCellWithIdentifier as long as the identifier matches one in your storyboard and your view controller is a UITableViewController.
You move the logic for the configuration of the cell to the custom table view cell, which is where it really should be. The view controller shouldn't care about the size of the image in the cell.
I am using this method to add an UILabel to my UITableView and its working fine, but I also need to create a method for selecting the row and save into an temp String.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10,10, 300, 30)];
[cell.contentView addSubview:label];
label.text = [tableArr objectAtIndex:indexPath.row];
label.font = [UIFont fontWithName:#"Whitney-Light" size:20.0];
return cell;
}
but its not working. It was working fine with when I was using cell.textLabel but not with the custom label.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell1 = [tableView cellForRowAtIndexPath:indexPath];
UILabel *lbltemp = cell1.textLabel;
_parent.labelone.text = lbltemp.text;
}
You could create your own UITableViewCell subclass to allow you to get the reference to your label (and prevent you from creating multiple labels on the cell). Or you could use tags like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell = nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10,10, 300, 30)];
label.tag = 123123;
[cell.contentView addSubview:label];
}
UILabel *label = (UILabel *)[cell viewWithTag:123123];
label.text = [tableArr objectAtIndex:indexPath.row];
label.font = [UIFont fontWithName:#"Whitney-Light" size:20.0];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UILabel *label = (UILabel *)[cell viewWithTag:123123];
_parent.labelone.text = label.text;
}
Your original code was adding a new label but then trying to get the text from the default label... It was also always creating a new cell and adding a new label to it which is quite wasteful.
Also, you shouldn't usually store text in the label, you should really to to your tableArr to get the text. The tag approach is more suited to updating the label when you reuse the cell or if you're letting the user edit the text (in a UITextField).
The reason it's not working is that you're not referencing the custom label in didSelectRowAtIndexPath. The easiest way to get a reference to the custom label is using tags:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
// Also, this is the proper way to use reuseIdentifier (your code is incorrect)
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10,10, 300, 30)];
[cell.contentView addSubview:label];
label.text = [tableArr objectAtIndex:indexPath.row];
label.font = [UIFont fontWithName:#"Whitney-Light" size:20.0];
label.tag = 1;
return cell;
}
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
UITableViewCell *cell1 = [tableView cellForRowAtIndexPath:indexPath];
UILabel *customLabel = [cell viewWithTag:1];
_parent.labelone.text = customLabel.text;
}
The problem is cell1.textLabel is not the label you created. It's simply the default Label created by the cell.
The solution could be:
Add a tag to the your label when you create your custom cell.
Say label.tag=100;
In didSelectRow,
Use
UILabel *lbltemp=(UILabel *)[cell1.contentView viewWithTag:100];
then _parent.labelone.text=lbltemp.text; should grab your text from that label.
Here ([cell.contentView addSubview:label];_) you are creating your custom label and adding it as subview to cell's content view but in UILabel *lbltemp = cell1.textLabel; you are trying to access the default label of tableview cell .Add some identifier(like tag) to your label and access it in didSelectRowAtIndexPath .
I think you can use default label and refuse from this workaround
just add
cell.textLabel.frame = CGRectMake(10,10, 300, 30);
Also it's better for memory to reuse cells as in Wain's answer
use cell.indentationallevel or cell.indentationwidth
I am using FontLabel in the view cells of the table.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
FontLabel *author_name = [[FontLabel alloc] initWithFrame:CGRectMake(58, 10, 217, 16) fontName:#"MyriadPro-Bold" pointSize:12.0f];
author_name.numberOfLines = 1;
author_name.text = [dummyArray objectAtIndex:indexPath.row];
author_name.textColor = [UIColor colorWithRed:0.580 green:0.776 blue:0.329 alpha:1.000];
author_name.backgroundColor = [UIColor clearColor];
[cell addSubview:author_name];
return cell;
}
But the label is loaded multiple times. I can see that it is getting bolder and bolder. How can I fix it?
When you call addSubview, it's not removing the old view. remember that cells are reused so the view you added in the last iteration is still there.
You should instead subclass UITableViewCell so that you can add a UILabel to it.
Edit:
Or you can do
author_name.tag = 10;
and then
FontLabel *author_name = (FontLabel *)[cell.contentView viewWithTag:10];
when you want to retrieve it.