I am wondering what is the best way to make a UITextField fit a UITableView cell.
I have used this method before:
#implementation UITextField (custom)
- (CGRect)textRectForBounds:(CGRect)bounds {
return CGRectMake(bounds.origin.x + 0, bounds.origin.y + 10,
bounds.size.width - 30, bounds.size.height - 16);
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
return [self textRectForBounds:bounds];
}
#end
But this causes an issue:
Category is implementing a method which will also be implemented by its primary class
Although I have seen ways to hide these warnings, it feels like this is more of a hack than a correct method.
What is the best way to fit a UItextField to a cell. This is my field:
// Username field
usernameField = [[UITextField alloc] initWithFrame:(CGRectMake(10, 0, 300, 43))];
usernameField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
It is input into the cell like this:
if (indexPath.row == 0) {
[cell.contentView addSubview:usernameField];
}
Image:
I'd suggest doing this by overriding your custom UITableViewCell's layoutSubviews method. Much simpler there imo. Something like:
- (void)layoutSubviews
{
[super layoutSubviews];
float w, h;
w = (int)(self.frame.size.width - 30);
h = (int)(self.frame.size.height - 16);
[self.detailTextLabel setFrame:CGRectMake(0, 10, w, h)];
}
Here's a fragment of the custom cell initialization
#interface MyCustomCell: UITableViewCell {
}
#end
#implementation MyCustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
}
return self;
}
Here's a fragment of where the custom cell would be created:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
MyCustomCell *cell = (MyCustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[MyCustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
Related
I'm trying to have dynamic cell heights. I've created a custom cell programmatically. Now I want the cell to change in height, but it seems to always be returning 44 which is the default tableviewcell height. Why is this?
- (void)viewDidLoad {
[super viewDidLoad];
[self.reminderTableView registerClass:[ReminderTableViewCell class] forCellReuseIdentifier:#"Daybreak-Cell"];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath;
{
if (indexPath.row > 3) {
return 60;
}
return 70;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"Custom-Cell" forIndexPath:indexPath];
...
return cell;
}
Custom Cell
#implementation CustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
NSLog(#"HEIGHT: %f",self.frame.size.height);
// Initialization code
[self.contentView setFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, kDefaultTableViewCellHeight)];
[self setBackgroundColor:[UIColor clearColor]];
[self createViews];
}
return self;
}
All you need to do, starting with iOS7 i believe, is:
self.tableView.estimatedRowHeight = 100.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
to get the cell to be of a dynamic height, also don't forget to put constraints within your cell from top to the bottom
JUST ensure that you are setting your table's delegate to be the class containing
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath;
{
if (indexPath.row > 3) {
return 60;
}
return 70;
}
As this method works with me
Hey everybody :) i try to change the width of my cells so there is a little space between the cells and the tableview border. I tried everything i could found here on stackoverflow, but without success.
I created the tableview with the interface builder, so first i simple tried to set the tableview size to "freeform" and dragged the width to 300.0f, but nothing happenend. Than i tried to do it programmatically in my "viewDidLoad" with:
self.tableView.frame = CGRectMake(10.0f, self.tableView.frame.origin.y, 300.0f, self.tableView.frame.size.height);
but here also nothing happens.... than i tried to change the cells directly with:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
GTNewsCustomCell *newsCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
newsCell.contentView.frame = CGRectMake(10.0f, 0, 300, newsCell.frame.size.height);
}
but same Problem here....any ideas what I missing?
EDIT: Another Solution for this Problem is to change the frame of the Custom Cell with:
- (void)setFrame:(CGRect)frame {
frame.origin.x += inset;
frame.size.width -= 2 * inset;
[super setFrame:frame];
}
just try this
in your custom cell put a property like
in .h file
#interface GTNewsCustomCell : UITableViewCell
#property (nonatomic, assign)CGRect cellFrame;
in .m file
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
self.backgroundColor = [UIColor greenColor];//for testing purpose only
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
//automatically called
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect cellRect = self.bounds;
cellRect.size.width = self.cellFrame.size.width;
self.bounds = cellRect;
}
.in .m of viewController
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
GTNewsCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if(cell == nil)
{
cell = [[GTNewsCustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
cell.cellFrame = CGRectMake(10, 0, tableRect.size.width,40);//hear tableRect is the frame of your tableview
return cell;
}
not sure try this hope this helps u
For this, first of all you can take an UIImageView to cover your full view and set its image as a bordered image. Now add a table view on this imageview with making width so as the borders of this image is visible.
I think you want dynamic Height for the Tableviewcell instead of width.
Delegate method of UITableView will help on this:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
Which will return height of every cell. You can implement it as following sample code. This is showing dynamic height on the basis of dynamic text content.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
//set width depending on device orientation
self.cellPrototype.frame = CGRectMake(self.cellPrototype.frame.origin.x, self.cellPrototype.frame.origin.y, tableView.frame.size.width, self.cellPrototype.frame.size.height);
CGFloat quotationLabelHeight = [self sizeOfLabel:self.cellPrototype.quotationLabel withText:[self quotationTextForRow:indexPath.row]].height;
CGFloat attributionLabelHeight = [self sizeOfLabel:self.cellPrototype.attributionLabel withText:[self attributionTextForRow:indexPath.row]].height;
CGFloat padding = self.cellPrototype.quotationLabel.frame.origin.y;
CGFloat combinedHeight = padding + quotationLabelHeight + padding/2 + attributionLabelHeight + padding;
CGFloat minHeight = padding + self.cellPrototype.avatarButton.frame.size.height + padding;
return MAX(combinedHeight, minHeight);
}
You can try with this too.
Use this:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
delegate method of UITableView and return a float value (CellHight+space bw cells).
I am using grouped UITableview with custom cell.My tableview consists of two sections.I need to change textfield frame only for two rows in section zero.How to possible??Please help me.Go through my code
customcell.m
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
self.textfiled1 = [[UITextField alloc]init];
self.textfiled1.returnKeyType = UIReturnKeyNext;
textfiled1.clearButtonMode = UITextFieldViewModeWhileEditing;
[self.contentView addSubview:self.textfiled1];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
}
-(void)layoutSubviews{
[super layoutSubviews];
self.textfiled1.frame = CGRectMake(50, 3, 250,40);
}
#pragma Tableview Delegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 0)
{
static NSString *CellIdentifier = #"Cell";
customcell*cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[customcell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSeparatorStyleNone;
}
cell.textfiled1.delegate = self;
if (indexPath.row==0) {
cell.textfiled1.frame = CGRectMake(50,3,180,40);//Change textfield frame
cell.separatorInset = UIEdgeInsetsMake(0, 50, 0, 100);
}
else if(indexPath.row==1)
{
cell.textfiled1.frame = CGRectMake(50,3,180,40);//Change textfield frame
}
else if(indexPath.row==2)
{
cell.textfiled1.keyboardType = UIKeyboardTypePhonePad;
}
else if(indexPath.row==3)
{
}
return cell;
}
else if(indexPath.section == 1)
{
static NSString *CellIdentifier1 = #"Cell1";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1];
}
cell.textLabel.text = #“Section1";
return cell;
}
}
Insted of this make a property so that u can set the specified frame u want hear the code, in controller u need to set frame for each cell see the code below
//CustomCell.h file
#interface CustomCell : UITableViewCell
#property(nonatomic,assign) CGRect TextFieldFrame;//put this to change the frame
#property (nonatomic,retain)UITextField *textfiled1;
#end
//in CustomCell.m file
#import "CustomCell.h"
#implementation CustomCell
#synthesize TextFieldFrame;//sysnthesise
#synthesize textfiled1;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.textfiled1 = [[UITextField alloc]init];
self.textfiled1.backgroundColor = [UIColor greenColor];
self.textfiled1.returnKeyType = UIReturnKeyNext;
textfiled1.clearButtonMode = UITextFieldViewModeWhileEditing;
[self.contentView addSubview:self.textfiled1];
}
return self;
}
-(void)layoutSubviews{
[super layoutSubviews];
self.textfiled1.frame = CGRectMake(self.bounds.origin.x + self.TextFieldFrame.origin.x, self.bounds.origin.y + self.TextFieldFrame.origin.y, self.TextFieldFrame.size.width, self.TextFieldFrame.size.height);
// self.textfiled1.frame = CGRectMake(50, 3, 250,40);//hear u are setting the contant frame thats wy frames are not changed
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
//in ViewController.m file
#import "ViewController.h"
#import "CustomCell.h"
#interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
#end
#implementation ViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 0)
{
static NSString *CellIdentifier = #"Cell";
CustomCell*cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSeparatorStyleNone;
}
cell.textfiled1.delegate = self;
if (indexPath.row==0) {
cell.TextFieldFrame = CGRectMake(50,3,180,40);//Change textfield frame, u can set the frame for each cell hear
cell.separatorInset = UIEdgeInsetsMake(0, 50, 0, 100);
}
else if(indexPath.row==1)
{
cell.TextFieldFrame = CGRectMake(50,3,180,40);//Change textfield frame, heare also
}
return cell;
}
else if (indexPath.section == 1)
{
static NSString *CellIdentifier = #"Cell_2";
CustomCell*cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSeparatorStyleNone;
}
cell.textfiled1.delegate = self;
if(indexPath.row==0)
{
cell.textfiled1.keyboardType = UIKeyboardTypePhonePad;
cell.TextFieldFrame = CGRectMake(80, 3, 180, 40); //for other cells default frame u need to set it heare
}
else if(indexPath.row==1)
{
cell.textfiled1.keyboardType = UIKeyboardTypePhonePad;
cell.TextFieldFrame = CGRectMake(80, 3, 180, 40);
}
return cell;
}
else
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
}
Create a custom table view cell initializer and pass indexpath . So now in tableview cell you know the row, based on row number make the changes
I am trying to create a (not very) custom UITableView with a button on the left side of the cell, and text to the right of the button.
I try to calculate where to put the UILabel that is part of the cell but changing the frame has no effect (and it doesn't even appear to be computed -- all zeros).
My question is: when is the frame size for the label computed? (So that changes will have an effect).
Is this the right way to do it?
Code snippets below.
First is from the cell init (called in response to the dequeueReusable...
and yes, 'buttonColor', 'onTapSel', 'buttonFrame', and 'buttonColor' are "member variables (File static globals)
- (id)initWithStyle: (UITableViewCellStyle)style
reuseIdentifier: (NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (nil == buttonColor)
{ buttonColor = kDefaultCellButtonColor; }
if (nil == onTapSel)
{ onTapSel = #selector(defaultCellButtonTapped:); }
if (self)
{
EGCellButton * cellButton = (EGCellButton *)[[EGCellButton alloc ] initWithFrame:buttonFrame ];
cellButton.backgroundColor = buttonColor;
[cellButton setTitle:buttonLabel forState:UIControlStateNormal];
[cellButton addTarget:self action:(onTapSel) forControlEvents: UIControlEventTouchUpInside];
[self setCellButton:cellButton];
float xx = buttonFrame.origin.x + buttonFrame.size.width + 5;
CGRect frame = self.textLabel.frame;
frame.origin.x += xx;
self.textLabel.frame = frame;
[self addSubview:cellButton];
}
return self;
}
and now from the cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"EGButtonTableCellID";
EGButtonTableCell * cell = (EGButtonTableCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.cellButton.indexPath = indexPath;
// Configure the cell...
cell.textLabel.text = #"abcdefghijklmnopqrstuvwxyz";
float xx = cell.cellButton.frame.origin.x + cell.cellButton.frame.size.width + 5;
CGRect frame = cell.textLabel.frame;
frame.origin.x += xx;
cell.textLabel.frame = frame;
return cell;
}
The result being that the button appears on the left side of the cell (as intended), but the first letter I see in the label is 'g', so the first 6 chars are hidden behind the button (not intended).
When I dump the values in the frame, all except origin.x are zero in both methods.
This should work, yes? no? why not? etc.
Thank you all very much!
:bp:
Set frame for your UILabel and UIButton in layoutSubviews method of your custom UITableViewCell
See Apple Documentation on the subject:
Subclasses can override this method as needed to perform more precise
layout of their subviews. You should override this method only if the
autoresizing and constraint-based behaviors of the subviews do not
offer the behavior you want. You can use your implementation to set
the frame rectangles of your subviews directly.
You can create a custom UITableViewCell, access objects in the class or implement methods.
CustomCell.h
#import <UIKit/UIKit.h>
#interface CustomCell : UITableViewCell
#property (nonatomic, retain) UILabel *customCellLabel;
#property (nonatomic, retain) UIButton *customCellButton;
#end
CustomCell.m
#import "TLCell.h"
#implementation CustomCell
#synthesize customCellLabel, customCellButton
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
customCellLabel = [[UILabel alloc] init];
customCellLabel.frame = CGRectMake(180, 0, 60, 30);
[self addSubview:customCellLabel];
customCellButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
customCellButton.frame = CGRectMake(0, 0, 60, 30);
[self addSubview:customCellButton];
}
return self;
}
#end
CustomTableView.m
/* --- */
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"Cell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
[cell.customLabel setText:#"hello"];
// [cell.
[cell.customButton addTarget:self action:#selector(yourMethod:) forControlEvents:UIControlEventTouchUpInside];
}
/* --- */
This is really stumping me. I know how to change the height of a UITableViewCell in heightForRowAtIndexPath. The issue if that I am trying to get two cells to sometimes overlap - so sometimes I need the frame of the cell in question to be higher than the height of the row. I know how to do this for the initial display of the cell by subclassing the custom cell and overriding the setFrame method. But once the cell displays, it seems that I cannot manually change the frame. Again - I am not talking about using heightForRowAtIndexPath here or tableview.rowHeight - I am talking about leaving the row height and manually changing the frame of the cell (possibly multiple times) after it has been displayed. Can anyone help me out?
Ok i dont no i got ur question or not, comment if there is any thing missed, i am posting the sample code to change the frame of custom cell manually by setting the different frame for each cell, in my code by tapping a button the frame of last cell is changed each time. Try it out this might u needed i dont no what u exactly want. Hope this Helps :)
//in CustomCell.h file
#import <UIKit/UIKit.h>
#interface CustomCell : UITableViewCell
{
}
#property(nonatomic, assign) CGRect frameRect;
#end
//CustomCell.m file
#import "CustomCell.h"
#implementation CustomCell
#synthesize frameRect;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)layoutSubviews
{
// always try to set frame in layoutSubviews
[super layoutSubviews];
self.frame = frameRect;
}
//in ViewController.h file
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<CountdownTimerDelegate>
- (IBAction)changeFrame:(id)sender;
#end
//ViewController.m file
#import "ViewController.h"
#import "CustomCell.h"
#interface ViewController ()<UITableViewDataSource, UITableViewDelegate>//delegate
{
CGRect aChangableRect; //your changeable frame
int k;
int yPos;
}
- (void)viewDidLoad
{
k = 25;
yPos = 220;
aChangableRect = CGRectMake(10,440, 50, 30);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//initially set it no for all cell
CustomCell *cell = [self.aTableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
if(indexPath.section == 0)
{
if(indexPath.row == 0)
{
cell.frameRect = CGRectMake(13, 5, 150, 50);
}
else if (indexPath.row == 1)
{
cell.frameRect = CGRectMake(5,60 , 200, 45);
}
}
else if(indexPath.section == 1) //second section
{
if(indexPath.row == 0)
{
cell.frameRect = CGRectMake(13, 110, 150, 50);
}
else if (indexPath.row == 1)
{
cell.frameRect = CGRectMake(5,165 , 200, 45);
}
}
else
{
// cell.frameRect = aChangableRect; //for last cell of last section
if(indexPath.row == 0)
{
cell.frameRect = CGRectMake(13, 220, 150, 50);
}
else if (indexPath.row == 1)
{
cell.frameRect = aChangableRect;
}
}
cell.textLabel.text = #"happy coding";
return cell;
}
//i am cganging the frame of last cell each time button clicked
- (IBAction)changeFrame:(id)sender
{
aChangableRect = CGRectMake(25, 450 , k * 2, k * 3);
[self.aTableView reloadData];
k = k + 10;
}