EDIT
My constraints on custom cells are all weird. Please disregard. Just using standard Left Detail ones now.
I don't understand why in iOS8 now my static table view cell contents are collapsing into the header of each section.
There's really almost nothing in my SettingsTVC.m. This is a just a test with all static data in the storyboard:
- (void)viewDidLoad {
[super viewDidLoad];
}
Have you implemented TableView delegate methods properly i.e
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if(section == CUSTOM_SECTION)
{
return CUSTOM_VALUE;
}
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return height;
}
Related
I am trying to change the elements on my section footer directly as it finish loading
But when i try following way
-(void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section {
UITableViewHeaderFooterView* footerView = [self.tableView footerViewForSection:0];
}
footerView returns nil
The only solution that works for me is performSelector:withObject:afterDelay
Shouldn't there exist a delegate method like the one mentioned above but with didDisplayFooterView instead?
Thanks :)
Your footer view is passed in as a the parameter view. Just check that the section is the one you want:
-(void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection: (NSInteger)section {
if(section == 0) {
//view is your footer view
}
}
How can I adjust a UITableViewCell so that it would show two fields after swiping it left - identical to how the mail client does it?
Right now I only see the "Delete" button.
I would like to have the "More" field included there, too...
Also, for the first if clause Cell I do not get a "Insert" field.
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row == self.reports.count){
return UITableViewCellEditingStyleInsert;
} else {
return UITableViewCellEditingStyleDelete;
}
}
Is there a way to combine the fields with the | operator or something?
Thanks, EL-
You can use undocumented delegate methods for UITableView in iOS7
- (NSString *)tableView:(UITableView *)tableView titleForSwipeAccessoryButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
return #"More";
}
- (void)tableView:(UITableView *)tableView swipeAccessoryButtonPushedForRowAtIndexPath:(NSIndexPath *)indexPath
{
[self setEditing:NO animated:YES];
}
It seems that they are not private and can be submitted to appStore.
I have three different custom cells of different heights. How should I use,
heightForRowAtIndexPath
To set the specific cell's height up. Something allong the lines of this.
if ([CellIdentifier isEqualToString:#"Cell"]) {
return 200;}
No avail
copy the code that figures out what cell to use from cellForRowAtIndexPath: to heightForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cel;
NSString *CellIdentifier;
// whatever code you use to figure out what cell to use
if ([CellIdentifier isEqualToString:#"Cell"]) {
// create & configure "Cell"-cell
}
else {
// configure Standard cell
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier;
// whatever code you use to figure out what cell to use
if ([CellIdentifier isEqualToString:#"Cell"]) {
return 200.0f;
}
else {
return 44.0f;
}
}
I have a UITableView that uses prototype cells to recreate a table. I have the first row with height 30 and the rest default 44. I would like to change only first row's height but have failed to do so. I tried cellForRowAtIndexPath but I learned here that it's heightForRowAtIndexPath: I'm interested in. However, all the IndexPath's that get sent to it are [0,0]. Can anyone help?
Have you tried this?
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) { //first row
return 30;
}
else {
return 44;
}
}
Do this for resizing the cells in your table views delegate.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0)
return 30.0;
return 44.0;
}
If this doesn't work: give us your code
I'm trying to load a single custom cell into a UITableView and it keeps throwing an error
UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:
I have no idea why. I have linked my table view cell to the UITableViewCell definition in my code, but it keeps giving me this error. Here is my code; any help would be greatly appreciated.
#import "RegisterDeviceViewController.h"
#implementation RegisterDeviceViewController
#synthesize checkString;
#synthesize cellRegistration;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
//Change UITableView Style to Grouped
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
style = UITableViewStyleGrouped;
if (self = [super initWithStyle:style]) {
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
self.title = #"Registration";
[super viewDidLoad];
}
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 1) {
if (indexPath.row == 1) {
return cellRegistration;
}
}
return nil;
}
//Pass search type over to rootViewController section2
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
Okay. That's not how UITableView works. When the table view needs to draw a cell (ie, a row); it invokes tableView:cellForRowAtIndexPath: on the object specified in the dataSource property. It's your job to return a UITableViewCell from that method. This is how Apple does it (and how you should do it):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"AnIdentifierString"];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"AnIdentifierString"] autorelease];
}
cell.textLabel.text = #"This text will appear in the cell";
return cell;
}
The number of times that method will be invoked depends on the number of sections in the table view and the number of rows in each section. The process works like this:
Table View invokes the delegate method numberOfSectionsInTableView: on its dataSource (it knows it implements that method because the dataSource must adhere to the UITableViewDataSource protocol).
If numberOfSectionsInTableView: returns a number greater than zero, the table view will invoke the delegate method tableView:numberOfRowsInSection: on the dataSource. So if numberOfSectionsInTableView: returns 2, tableView:numberOfRowsInSection: will be invoked twice.
If each invocation of tableView:numberOfRowsInSection: returns a number greater than zero, the table view will invoke the delegate method tableView:cellForRowAtIndexPath: on the dataSource' So if tableView:numberOfRowsInSection: returns 5, tableView:numberOfRowsInSection: will be invoked five times (once for each individual row).
Your opportunity to customise how that cell appears is after you've received a useable cell, but before it is returned (where 'This text will appear in the cell' appears above). You can do quite a lot here; you should see the Class Reference for UITableViewCell to see everything you can do (all I've done is set it to show 'This text...'). The lines above that are a way for iOS to reuse cells for performance considerations. If you, for example, wanted to show a certain string from an array of strings, you could do this (notice the use of the indexPath variable): cell.textLabel.text = [someArrayYouHave objectAtIndex:indexPath.row];.
You wrote:
it keeps throwing an error
'UITableView dataSource must return a
cell from
tableView:cellForRowAtIndexPath:' But
I have no idea why..
But your -tableView:cellForRowAtIndexPath: says, in part:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//...
return nil;
}
After reading the error message and looking at the code, do you not see the problem?
You are returning only one section, only one row
the section count and row count starts from 0.
Thats y you are getting this kinda error
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
if (indexPath.row == 0) {
//this checking is no necessary, anyway if you want use like this
//ensure that cellRegistration is UITableViewCell
return cellRegistration;
}
}
return nil;
}
Also refer this post for loading custom cells.
New iOS7+ solution optimized for Smoother Scrolling
You already can see old solutions but as far as huge amount of Apps will continue only iOS7+ support here is a way more optimized and correct solution.
Cell initialization
To initialize cell just call dequeueReusableCellWithIdentifier and iOS7+ systems are enough smart to handle if cell == nil or not. If during dequeue cell is nil system will automatically make a cell for you.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellIdentifier" forIndexPath:indexPath];
return cell;
}
Cell configuration
Then do your entire cell configuration in willDisplayCell method. Just create one method in your class that configures cell and here you go with better performance!
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[self configureCell:cell forRowAtIndexPath:indexPath];
}
- (void)configureCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath {
// Configure your cell
}