Before ios 5 I would set the row height in a tableview like this:
self.tableView.rowHeight=71;
However, it doesn't work on iOS5.
Someone has an idea?
Thanks
Have you tried tableView:heightForRowAtIndexPath: from UITableViewDelegate?
You may set the row height to 71 by implementing tableView:heightForRowAtIndexPath: in your UITableView delegate (one who supports the UITableViewDelegate protocol).
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 71.0;
}
First you should set a delegate of your tableView. Delegate should conform to the UITableViewDelegate protocol. Let's say we have a TableDelegate class. To conform to a UITableViewDelegate protocol one should have it in square brackets in it's declaration like this:
...
#interface TableDelegate : UIViewController <UITableViewDelegate>
...
or
#interface TableDelegate : UIViewController <some_other_protocol, UITableViewDelegate>
Then you set the delegate:
...
// create one first
TableDelegate* tableDelegate = [[TableDelegate alloc] init];
...
self.tableView.delegate = tableDelegate;
In the end you should implement the tableView:heightForRowAtIndexPath: method in the TableDelegate implementation:
#implementation TableDelegate
...
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 71.0;
}
...
#end
rowHeight
Just to clarify, using rowHeight should work just fine and perform better than constant returned from -tableView:heightForRowAtIndexPath: as Javier Soto points out in the comments. Also note, that if your UITableView has delegate returning height in -tableView:heightForRowAtIndexPath: and rowHeight property set, prior value is honoured.
Im coding for iOS 5 and it actually works. You just need to implement the line you said in the:
- (void)viewDidLoad
method after the:
[super viewDidLoad];
The:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
method does not work if the TableView is empty. But if you use the rowHeight property it will work even if the view is empty.
This method is change the Height of row
-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
return 51.0f
};
Try setting the rowHeight before viewWillAppear:, e.g. right after creating your table view.
This made it work for me on iOS 5. On iOS 6 it's easier: you can set it anywhere.
The advantage of using rowHeight, as pointed out by others, is that you avoid the performance impact of tableView:heightForRowAtIndexPath:.
Related
i am new to iOS, this may seem like a basic question. I have been working through this tutorial and I have no idea how the tableview is connected to the code. The sample project can be downloaded here.
I was my understanding that you need to extend UITableViewDelegate, UITableViewDataSource in the code, then in the storyboard you can drag from the tableview to them.
But what is perplexing is that the sample project does not extend UITableViewDelegate, UITableViewDataSource at all, therefore, how is the tableview in the story board connected to the code ?
Datasource is used to supply data and delegate is used to supply behaviour. UITableView asks your datasource every time it needs data to display. It provides a lot of flexibility for how you choose to represent your underlying data model. You simply define specific methods to use in order to get table information, and iOS can call them when it needs to know something like the number of rows in a section, or the content of a particular row.
You will probably implement your own delegate mechanism in the future. It is a great design pattern which handles interaction/data transfer between objects.
Because, the basic class adopts from UITableViewController
#interface WTTableViewController : UITableViewController
In your storyboard you just ctrl-drag from tableview to viewController and choose delegate and dataSource.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/ you should refer this it will help u alot
If you working with TableViewController, UITableViewDelegate and UITableViewDataSource are connected to table automatically. In case you are working with ViewControler which contains TableView, you have to add UITableViewDelegate and UITableViewDataSource like this: #interface myViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>. In new versions of Xcode you can drag delegate and data source to table, and if you want to set delegate programmatically, you can add this two lines of codes:
[tableView setDelegate:self];
[tableView setDataSource:self];
or, equally:
tableview.delegate = self;
tableview.dataSource = self;
In viewcontroller.h file e
declare the delegate and datasource method.
UIViewController<UITableViewDataSource,UITableViewDelegate>
then
connect the delegate and datasource method with viewController so
in viewController.m file
- (void)viewDidLoad {
tableview.delegate=self;
tableview.dataSource=self;
}
In Objective-C/iOS you often implement things by having classes conform to protocols rather than subclassing classes. WTTableViewController conforms to the protocols
UITableViewDataSource: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/
and
UITableViewDelegate: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/
In MainStoryboard.storyboard you can see in the inspector to the right that the TableViewController has a custom class of WTTableViewController
The relevant methods in WTTableViewController.m:
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"WeatherCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
}
Here's some general info about protocols: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithProtocols/WorkingwithProtocols.html
I suggest reading a beginners book or tutorial on iOS to pick up the overall design principles otherwise many things can be quite confusing.
I want to have the height of my UITableView cells depend on the material they contain. My view controller object is a subclass of UITableViewController and conforms to the <UITableViewDelegate> protocol. Is this the correct place to reference the protocol?
Then in my implementation I declare
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [indexPath row] * 20;
}
but when I run the app each row is of fixed height that is visually represented in the storyboard. Is it something with the prototype cell that is overriding my code? Am I missing something completely naive?
Did you set your view controller as delegate to table view. You can do it either through connection inspector of your table view in xib/ storyboard. Or you can do it by doing following in your initWithNibName:bundle: method
myTableView.delegate = self;
I try to display objects of an array in a tableview.
This is a single screen app, I'm using storyboard.
When running - the tableview appears as an empty grid. the data of the objects is not displayed. what may cause this?
Having 2 required methods numberOfRowsInSection and cellForRowAtIndexPath I suspect the last one.
The .h file contains this row:
#interface MYViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
I set the delegate & datasource via the code as you suggested. still empty grid.
This is my implementation:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [listRecipes.recipeArray count]; }
-(UITableViewCell )tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString cellIdentifier = #"ListCellIdentifier"; MYCustomListCell* listCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; NSString* dataString = listRecipes.recipeArray[indexPath.row]; listCell.listName.text = dataString; listCell.imageView.image = [UIImage imageNamed:dataString]; return listCell; }
I try to display data from an array in MVC .
If the array is local - the data is displayed
Can you please advise what to do?
Thank you in advanced.
Always remember to hook up your table's delegate and datasources.
Being a UIElement on a UIViewController that conforms to these two protocols is not enough for Xcode to assume that that UIViewController should be the delegate and/or datasource for the table.
Right click on your tableview, drag from delegate & datasource to your UIViewController.
You can also set these programmatically via:
self.table.datasource = self;
self.table.delegate = self;
And if you're still having trouble after this, you'll have to show us how you're implementing the datasource protocol methods.
Check if your initialisation of tableview delegate and datasource would be before the recipeArray is initialised. In this case you will have to tableView.reload() after the items are added to recipeArray .
I would like to have a UITableView with a UIWebView in each cell. The UIWebView should have the contentSize so that it shows its whole content without scrolling. My problem is the HeightForRowAtIndexPath because the content has to be loaded first before it can return a value.
I did something like this in this old and maybe no more up-to-date code:
https://github.com/Daij-Djan/DDUtils/tree/master/ui/M42WebviewTableViewCell%20%5Bios%5D
Disclaimer: My own open source code
How it works:
In the dataSource:
you return the cell's preferredHeight (which is 0 if there is no content)
you also implement the delegate - (void)tableCellDidLoadContent:(M42WebviewTableViewCell*)cell;
you reload your table which will invalidate all Heights. When you now return preferredHeight it is valid and the views appear alright.
I would subclass UITableViewCell in this (very MVC) way:
#interface CustomTableViewCell : UITableViewCell
#property (nonatomic,strong) id model;
+(CGFloat)heightForModel:(id)model;
#end
Model can be whatever your want. This is a very generic example.
In heightForModel you calculate the exact height of the cell.
In the init method of CustomTableViewCell, you should add a blank UIWebView to the cell.
When you "set" model property, you should refresh cell UI.
Then in the class that implements the delegate methods (assuming that cell models are stored in a NSArray called models):
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [CustomTableViewCell heightForModel:self.models[indexPath.row]];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([CustomTableViewCell class])];
cell.model = self.models[indexPath.row];
return cell;
}
Remember to register your custom cell!
I have a custom view EMViewController with a tableview as a subview. I want EMViewController to double as the controller for the subview, so I have it set as the delegate and dataSource.
// EMViewController.h
#interface EMViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
...
// EMViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.eTableView.delegate = self;
self.eTableView.dataSource = self;
}
I'm populating the data with an asynchronous array/dictionary from Facebook, so once I have the data, I run
[self.eTableView reloadData]
For the UITableViewDataSource protocol methods, I implemented the following:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(#"returns sections 0"); // This appears in my log
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"returning count %d", [self.eList count]); // never shows up
return [self.eList count];
}
- (EMTableViewCell *)tableView:(EMTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// configure the cell
NSLog(#"index: %d", indexPath); // never shows up
...
}
So far, I have already tried:
making sure my storyboard is connected up
checking/rechecking the delegate/dataSource being set in viewDidLoad
completely restarting/clean-building my app just in case
creating a placeholder UIView subclass (although I'm not changing much)
creating a customUITableViewCell class with outlets for my custom layout (images, 3 labels)
testing out strong/weak references to the tableView outlet
Any advice would be appreciated. I think my problem is similar to this question, except I'm trying to add the tableview as a subview. My end goal is to populate the cells with a custom format that includes an image and three labels. Thanks!
Return 1 section instead of returning 0 sections
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}