The code in questions is below:
-(void)addSpeedTable {
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"newCell"];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
self.tableView.rowHeight = 45;
self.tableView.sectionFooterHeight = 22;
self.tableView.sectionHeaderHeight = 22;
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView = _tableView;
NSLog(#"TableView Frame %#", NSStringFromCGRect(self.tableView.frame));
[self.view addSubview:self.tableView];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"newCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"newCell"];
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.textLabel.text = #"Test";
return cell;
}
As you can see if I have a section set to 1 and row set to 1, yet when the view is added the table takes up the entire screen, which I assume is because I initiate with a frame of the view bounds.
Is there any way to force the table to only be the size of the rows required?
My plan is to add more than one table to this single view and I want them appearing one after the other along with title labels and a scrollview. I want the height to be decided by the number of rows.
Thanks
UPDATED CODE THANKS TO THE CORRECT ANSWER:
-(void)addSpeedTable {
CGRect frame = self.tableView.frame;
frame.size.height = (40 * resultHeadings.count)+35;
frame.size.width = self.view.frame.size.width;
//If more than one table has been shown increase Y axis height for view
if(tablesDisplayed > 0) {
NSLog(#"Tables displayed greater than zero");
viewHeight = viewHeight + frame.size.height;
}
frame.origin.y = viewHeight;
frame.origin.x = 0;
self.tableView = [[UITableView alloc] initWithFrame:frame];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"newCell"];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
self.tableView.rowHeight = 40;
self.tableView.sectionFooterHeight = 0;
self.tableView.sectionHeaderHeight = 22;
self.tableView.scrollEnabled = NO; // Disable ScrollView
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView = _tableView;
NSLog(#"TableView Frame %#", NSStringFromCGRect(frame));
[self.view addSubview:self.tableView];
tablesDisplayed++;
}
As I'm adding more than one table in the long run I calculate the height based on a calculation. This works great.
Here are two things you could try. Without knowing where addSpeedTable is called from, I'd err on putting this in your cellForRowAtIndexPath method.
Set the height to the self.tableView.contentHeight
CGRect frame = self.tableView.frame;
frame.size.height = self.tableView.contentSize.height;
self.tableView.frame = frame;
Call [self.tableView sizeToFit]
Related
I'm working with a UITableView.
The table view has a HeaderView with a UIImageView that changes its height when the user scroll the table view.
In addition to this I also have a custom uiview for the section of the tableview .. My problem is that after setting the content Inset for the tableview, the section does not follow the scrolling of the table ..
Before Scroll
After Scroll
Surely it is a problem of content Inset, I did various tests but I could not find a solution ...
I would like the section of the tableView to follow the scroll and stop when it gets under the status bar (about 25 points of self.view.frame.origin.y)
Which path should I follow to solve my problem?
This is the code I am using
Register Xib for section header
- (void)viewDidLoad {
[super viewDidLoad];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellID];
[_tableView registerNib:[UINib nibWithNibName:#"DashboardTopHeader" bundle:nil] forHeaderFooterViewReuseIdentifier:dashboardTopHeader];
[self setupHeaderView];
}
Generate Section Header
#pragma mark - Dashboard Top Header
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
DashboardTopHeader *header = [tableView dequeueReusableHeaderFooterViewWithIdentifier:dashboardTopHeader];
return header;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 100;
}
Setup the Header View of TableView With Photo
-(void)setupHeaderView {
_headerView = [[UIView alloc] init];
_headerView = self.tableView.tableHeaderView;
_tableView.tableHeaderView = nil;
[_tableView addSubview:_headerView];
// 130 is Height of headerView
CGFloat newHeight = 130 - 50 /2;
_tableView.contentOffset = CGPointMake(0, -newHeight);
_tableView.contentInset = UIEdgeInsetsMake(newHeight, 0, 0, 0 );
[self updateHeaderView];
}
-(void)updateHeaderView {
CGFloat newHeight = 130 - 50 /2;
CGRect headerFrame = CGRectMake(0, -newHeight, self.tableView.frame.size.width, 130);
if (self.tableView.contentOffset.y < newHeight) {
headerFrame.origin.y = self.tableView.contentOffset.y;
headerFrame.size.height = - self.tableView.contentOffset.y + 50/2;
}
_headerView.frame = headerFrame;
}
Use TableView Delegate for scroll Content
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
[self updateHeaderView];
}
I'm trying to create a UITableview, where each cell contains another UITableView. It's basically a list of 2-3 rows, where each row then has a sublist of 2-3 rows inside.
The main ViewController behaves just like any other TableViewController, and inside the cellForRowAtIndexPath, it attempts to add a SubTableViewController.view with a dynamic height. The SubTableViewController is the second tableview and each has their own Datasource.
The problem I'm running into is the SubTableViewController appears to render properly using the debugger, with the correct data and number of cells, but it simply isn't appearing when rendering. I noticed it has a contentSize height of "0" in its ViewDidAppear, despite having 2+ rows produced with height. The project uses AutoLayout but the SubTableViewController's frame is set programmatically when added.
Any ideas what I can do to get something to appear here?
Structure of Data (periods are the subTable)
[{name:"activity 1",
periods:[{name:"period1",desc:"desc1"},
{name:"period2",desc:"desc2"},
{name:"period3",desc:"desc3"}
]
},
{name:"activity 2",
periods:[{name:"period1",desc:"desc1"},
{name:"period2",desc:"desc2"},
{name:"period3",desc:"desc3"}
]
}]
ViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_data count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
UIImageView *imageView = (UIImageView*)[cell viewWithTag:1];
UIView *subTableView = (UIView*)[cell viewWithTag:3];
return imageView.frame.size.height + subTableView.frame.size.height + 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"tableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
ActivityModel *model = _data[indexPath.row];
UILabel *nameLabel = (UILabel*)[cell viewWithTag:2];
nameLabel.text = model.name;
UIView *internalView = (UIView*)[cell viewWithTag:10];
SubTableViewController *subTableViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"SubTableViewController"];
subTableViewController.activityModel = model;
subTableViewController.view.tag = 3;
subTableViewController.view.frame = CGRectMake(0,
60,
internalView.frame.size.width,
subTableViewController.view.frame.size.height);
[internalView addSubview:subTableViewController.view];
[internalView bringSubviewToFront:subTableViewController.view];
[subTableViewController.tableView reloadData];
return cell;
}
SubTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
int height = 0;
for (int section = 0; section < [self numberOfSectionsInTableView:_tableView]; section++){
for(int row = 0; row < [self tableView:_tableView numberOfRowsInSection:section]; row++){
height += [self tableView:_tableView heightForRowAtIndexPath:[NSIndexPath indexPathForItem:row inSection:section]];
}
}
CGRect tableFrame = self.tableView.frame;
tableFrame.size.height = height;
self.tableView.frame = tableFrame;
CGRect viewFrame = self.view.frame;
viewFrame.size.height = height;
self.view.frame = viewFrame;
[self.view bringSubviewToFront:_tableView];
// [self.tableView layoutIfNeeded];
// [self.tableView setNeedsDisplay];
// [self.tableView reloadData];
// _tableView.contentSize = CGSizeMake(600, 52);
self.view.backgroundColor = [UIColor redColor];
self.tableView.backgroundColor = [UIColor blueColor];
self.tableView.hidden = NO;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [_activityModel.periods count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
UILabel *nameLabel = (UILabel*)[cell viewWithTag:3];
UITextView *textView = (UITextView*)[cell viewWithTag:5];
float textViewHeight = [textView.text sizeWithFont:[UIFont systemFontOfSize:13] constrainedToSize:CGSizeMake([UIScreen mainScreen].bounds.size.width - 40, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping].height;
return nameLabel.frame.size.height + textViewHeight + 20;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"tableViewCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
PeriodModel *model = _activityModel.periods[indexPath.row];
UILabel *nameLabel = (UILabel*)[cell viewWithTag:3];
UILabel *durationLabel = (UILabel*)[cell viewWithTag:4];
UITextView *textView = (UITextView*)[cell viewWithTag:5];
nameLabel.text = model.name;
durationLabel.text = [NSString stringWithFormat:#"%d minutes", (int)(model.durationSeconds/60)];
textView.text = model.description;
textView.textContainerInset = UIEdgeInsetsZero;
textView.textContainer.lineFragmentPadding = 0;
textView.scrollEnabled = NO;
CGRect frame = textView.frame;
frame.size.height = [textView.text sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:CGSizeMake(cell.contentView.frame.size.width, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping].height;
textView.frame = frame;
return cell;
}
Simulator Image. The title is the outer UITableCell, and below it in red is the added SubTableViewController.view. The UITableView should cover the red, but is not appearing at all here. It is not hidden, underneath, etc.
Do not put a table view inside your cells.
There is little benefit to doing this for your described use. Use sections and rows. Each section would be your current cell. And each row in that section would be a row from your current embedded table view.
Further, if your internal table views had differing sizes you would be needing to calculate all of the internal cell heights for each external cell. That is exactly what happens with sections and rows, but you as the developer only need to worry about the rows and UITableView will handle the section sizing.
I'm trying to add a UITableView to an existing UIViewController programmatically.
My run.h file has this:
#interface runTests : UIViewController <UINavigationControllerDelegate,UITextFieldDelegate,UIAlertViewDelegate,UITableViewDelegate,UITableViewDataSource> {NSTimer *Timer;}
#property (strong, nonatomic) UITableView *tableView;
My app runs through a speed test and at the end of the test I'm trying to add a TableView to the View. At the moment I have this:
-(void)addSpeedTable {
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
self.tableView.rowHeight = 45;
self.tableView.sectionFooterHeight = 22;
self.tableView.sectionHeaderHeight = 22;
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview:self.tableView];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"newCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Testing";
return cell;
}
The app never makes it into the cellForRowAtIndexPath method but does make it into the other two above. I can't see any error in the Xcode output.
Anything I need to be doing here:
When the app fails all I get is this:
If width of UITableView is zero, it will never call datasource
So change your code like this
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
Good luck!
You should init your UITableView with a frame (and optionally a style), or at least define the frame somewhere.
For example:
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 200, 200) style:UITableViewStylePlain];
You need to assign the property tableView to the instance you are creating in the addSpeedTable method, then reference it using self.tableView.
-(void)addSpeedTable {
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
self.tableView.rowHeight = 45;
self.tableView.sectionFooterHeight = 22;
self.tableView.sectionHeaderHeight = 22;
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview:self.tableView];
}
Edit
As pointed out by the other answers, you'll probably need to set the frame on the UITableView as well:
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
You use init method to initialize a view, which means the view's frame is CGRectZero.
So the numberOfRowsInSection is called but SDK finds no cell need to be shown as the frame is CGRectZero.
-(void)addSpeedTable {
.....
tableView.frame = self.view.bounds;
[self.view addSubview:tableView];
}
What's more you should assign your tableView to the property by self.tableView = tableView or your tableView property will never be valid state.
You can add breakpoint at the thirdLine, and print out the frame see if one of its bounds is 0.
I think you may have declare the wrong syntax. I can't upload image, So notice the difference the code below. The capitalization may be the problem.
{
// 服务条款
static NSString * cellId = #"justCommon";
static NSString *CellIdentifier = #"newCell";
}
I have one class ViewController that I to create TableView in it with code not nib file and I want custom cell with UITableViewCell that has nib file.
I create TableView with code that has 320px width and I want create custom cell with UITableViewCell that my cells had 300px width and put in my TableView.
notice: I want these cells put center my table and these cells have 10px distance from two side!!!
this is my code:
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
table = [self makeTableView];
[self.view addSubview:table];
[self.view setBackgroundColor: RGB(193,60,46)]; //will give a UIColor objct
name = [[NSArray alloc]initWithObjects:#"1",#"2",#"3",#"4",#"5", nil];
// Do any additional setup after loading the view from its nib.
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
-(UITableView *)makeTableView
{
CGFloat x = 0;
CGFloat y = 0;
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
CGRect tableFrame = CGRectMake(x, y, width, height);
UITableView *tableView = [[UITableView alloc]initWithFrame:tableFrame style:UITableViewStyleGrouped];
tableView.rowHeight = 60;
tableView.sectionFooterHeight = 22;
tableView.sectionHeaderHeight = 22;
tableView.scrollEnabled = YES;
tableView.showsVerticalScrollIndicator = YES;
tableView.userInteractionEnabled = YES;
tableView.bounces = YES;
tableView.backgroundColor = [UIColor clearColor];
tableView.delegate = self;
tableView.dataSource = self;
return tableView;
}
#pragma mark Table View Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = (CustomCell *)[self.table dequeueReusableCellWithIdentifier:#"myCell"];
if (cell == nil)
{
NSArray *topLevelObject = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:nil options:nil];
for (id currentObject in topLevelObject) {
if ([currentObject isKindOfClass:[CustomCell class]]) {
cell = (CustomCell *)currentObject;
break;
}
}
}
// Configure the cell...
cell.titleLable.text = [name objectAtIndex:indexPath.row];
return cell;
}
this is my code : TableCode
I have a UITableView with a width of 685.
I created Custom UITableViewCell with a width of 685 also.
I have added two labels.
I aligned a label in such a way, the spacing for left and right are the same.
afaik, cells are always the width of the table and you cant change that, you can fake it by making the content view of the cell transparent, then place another view with all your content in it that is a smaller width than the table
I have a strange issue. When I load my tableview that contains two textfields (one for email and one for password), I am only able to see the bottom of the cursor. It is as if there is something covering the input field (please see the image below). This issue only started when I went from targeting iOS6 to iOS7.
Any ideas what might be going wrong here?
Here is my code:
- (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];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
CGRect frame;
frame.origin.x = 10;
frame.origin.y = 10;
frame.size.height = 30;
frame.size.width = 200;
UILabel *label = [[UILabel alloc] initWithFrame: frame];
label.font = [UIFont boldSystemFontOfSize:16.0];
label.text = [arrayLogin objectAtIndex:indexPath.row];
[cell.contentView addSubview:label];
frame.origin.x = 10;
frame.size.height = 90;
frame.size.width = 280;
if (indexPath.row == 0) {//user name part
userNameTextField = [[UITextField alloc ] initWithFrame: frame];
userNameTextField.returnKeyType = UIReturnKeyDefault;
userNameTextField.delegate = self;
userNameTextField.placeholder = #"Email";
[cell.contentView addSubview:userNameTextField];
}else
{
passwordTextField = [[UITextField alloc] initWithFrame:frame];
passwordTextField.returnKeyType = UIReturnKeyDefault;
passwordTextField.secureTextEntry = YES;
passwordTextField.delegate = self;
passwordTextField.placeholder = #"Password";
[cell.contentView addSubview:passwordTextField];
}
return cell;
}
The default row height is 44 (not sure -anyway close to it.)
In your code you are using frame.size.height = 90; which you are adding as subView in your cell.
So it is exceeds your cell height.
To make custom cell height you should change the following delegate method:
-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
//NSLog(#"HeightForRow");
return 44+50;//ofcourse change it as you wish
}
also I think you want to change the frame.origin.y for the textField to 42
and text frame.size.height to 90 -42