- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1) {
return NO;
}
else {
return YES;
}
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1) {
return NO;
}
else {
return YES;
}
}
I have 2 sections in my tableView. I want my tableViewcells to be moved only in first section(not for second). Currently if i drag my tableCell to second section, It has a crash.
I think you are looking for this method -
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if (proposedDestinationIndexPath.section != 0)
{
return sourceIndexPath;
}
return proposedDestinationIndexPath;
}
It will restrict you to move your rows in section 0 only. If you try to move row from section 0 to 1, it'll return the previous indexpath of the cell
Related
Hi everyone I am a newbie to iOS.
I have implemented a UITableView with 3 sections in UITableViewController. And I have displayed the section rows to each section.
- (void)viewDidLoad
{
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = NO;
self.navigationItem.rightBarButtonItem = self.editButtonItem;
sectionTittle=[[NSMutableArray alloc]initWithObjects:#"Real Madrid",#"Barcelona",#"Liverpool", nil];
firstSection=[[NSMutableArray alloc]initWithObjects:#"Cr7",#"Garath Bale",#"Pepe",
nil];
secondSection=[[NSMutableArray alloc]initWithObjects:#"Lionel Messi",#"Neymar",#"Pique",
nil];
thirdSection=[[NSMutableArray alloc]initWithObjects:#"Gerrard",#"Saurez",#"Lallana",
nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return sectionTittle.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(section==0)
{
return [firstSection count];
}
if(section==1)
{
return [secondSection count];
}
if(section==2)
{
return [thirdSection count];
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"hi" forIndexPath:indexPath];
cell.textLabel.textColor=[UIColor brownColor];
if (indexPath.section == 0)
{
cell.textLabel.text=[firstSection objectAtIndex:indexPath.row];
}
if (indexPath.section == 1)
{
cell.textLabel.text = [secondSection objectAtIndex:indexPath.row];
}
if (indexPath.section == 2)
{
cell.textLabel.text = [thirdSection objectAtIndex:indexPath.row];
}
// Configure the cell...
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [sectionTittle objectAtIndex:section];
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
Now my output looks like this:
I want to move the rows between the these 3 sections. How can I do it..? While I try doing it the row moves between the section, but while saving it creates a problem.
How can i go through it..?
Thanks
You need to utilise UITableView re-ordering capacity. The cells can be re-ordered across sections.
To enable re-ordering mode:
[self.tableView setEditing:TRUE animated:TRUE];
This enables the TableView in editing mode which includes enables deletion mode along with re-ordering. If you do not want the deletion mode implement:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleNone;
}
The re-order support accessory view is shown if you have implemented moveRowAtIndexPath like, for your case:
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
// Logic to change data source
NSMutableArray *deleteFrom = [self getDataSourceArrayFromIndexPath:sourceIndexPath];
NSMutableArray *addTo = [self getDataSourceArrayFromIndexPath:destinationIndexPath];
[addTo insertObject:[deleteFrom objectAtIndex:sourceIndexPath.row] atIndex:destinationIndexPath.row];
[deleteFrom removeObjectAtIndex:sourceIndexPath.row];
}
where getDataSourceArrayFromIndexPath is:
-(NSMutableArray*) getDataSourceArrayFromIndexPath:(NSIndexPath*) index
{
switch (index.section) {
case 0:
return self.firstSection;
break;
case 1:
return self.secondSection;
break;
case 2:
return self.thirdSection;
break;
default:
break;
}
return nil;
}
Use This Code
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
NSMutableArray *arrayTemp=[arrayMain objectAtIndex:sourceIndexPath.row];
[arrayVisibleCountryList removeObjectAtIndex:sourceIndexPath.row];
[arrayVisibleCountryList insertObject:arrayTemp atIndex:destinationIndexPath.row];
}
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
//Uncomment these lines to enable moving a row just within it's current section
if ([sourceIndexPath section] != [proposedDestinationIndexPath section])
{
proposedDestinationIndexPath = sourceIndexPath;
}
return proposedDestinationIndexPath;
}
You can use below tableView method. It moves your cell from sourceIndexPath to destinationIndexPath.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
I need add an ad cell with only image after every five news cells in table view.
If I will add second section for ad cells, an ad cell will be shown after all news cells.
If I will add an ad cell when indexPath.row == 4, my fifth news cell won't appear because of cell.details = news[indexPath.row].
Any suggestions how can I do that? Thanks.
In the method cellForRowAtIndexPath of UITableViewDataSource do next:
if (indexPath.row % 5 == 0) {
// configure ad cell
} else {
// configure usual cell with news[indexPath.row - (indexPath.row / 5)]
}
You need to figure out a system to get the right data for your cells:
0 NEWS
1 NEWS
2 NEWS
3 NEWS
4 NEWS
5 AD <----- "5." => (currentRow % 5 == 0)
6 NEWS <----- "6." => (6 - (currentRow / 5)
You see a system?
You can do something like:
if ((row % 5) == 0) {
//Ad stuff here
} else {
data = tabledata[row - (row/5)];
//news stuff here using data
}
do like this ..
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 4;//add your own number, might be totalNumberOfNewsItems/5
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int reqIndex = indexPath.section*(5) + indexPath.row;
// get data from array like news[reqIndex];
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
// return your ad view based on section value
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 44; // change to your required value
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row % 5 == 0) {
//configure ad cell
} else {
//configure usual cell
}
}
I have two UITableViews in the same ViewController, one which uses dynamic height based on UILabel content size and the other where all the cells are static heights. I separated the two TableViews using tags. I tried using this:
self.tableView1.rowHeight = UITableViewAutomaticDimension;
and:
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView.tag == 1) {
return 114.0f;
} else {
if (indexPath.section == 0) {
return 50.0f;
} else if (indexPath.section == 2) {
return 20.0f;
} else {
return 44.0f;
}
}
}
The problem is that the dynamic cells do not change dynamically and the static height cells originally have the right height but when they scroll out of the view they then change to the default height for cells.
Can anyone help please?
When you implement:
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
You need implement both this and
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Normally It´s the same code, add this to your protect:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.tag == 1) {
return 114.0f;
} else {
if (indexPath.section == 0) {
return 50.0f;
} else if (indexPath.section == 2) {
return 20.0f;
} else {
return 44.0f;
}
}
}
I've looked around at other questions here and many other sources online and just can't find a solution. I have 3 rows and no matter what I do, they all keep the width defined in the tableview. The first one is what I want, but the second and 3rd I can't give a custom height.
Below is my code:
#import "DetailTableViewController.h"
#import "EventDetailTableViewCell.h"
#import "EventDescriptionTableViewCell.h"
#import "EventMapTableViewCell.h"
#interface DetailTableViewController ()
#end
#implementation DetailTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0) {
static NSString *CellIdentifier = #"headerCell";
EventDetailTableViewCell *headerCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
headerCell.headerImage.image = [UIImage imageNamed:#"img4.png"];
return headerCell;
} else if (indexPath.section == 1) {
static NSString *CellIdentifier = #"descriptionCell";
EventDescriptionTableViewCell *descriptionCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
descriptionCell.descriptionImage.image = [UIImage imageNamed:#"img2.png"];
return descriptionCell;
} else {
static NSString *CellIdentifier = #"mapCell";
EventMapTableViewCell *mapCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return mapCell;
}
}
#pragma mark - Helper Methods
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == 1) {
return #" ";
} else if (section == 2) {
return #" ";
} else {
return nil;
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
return 222;
} else if (indexPath.row == 1) {
return 80;
} else {
return 100;
}
}
#end
I believe there is a mistake in your code in heightForRowAtIndexPath. You have been using indexPath.sectionfor most of your TableView delegate and dataSource methods. So, I believe you want to use indexPath.section on heightForRowAtIndexPath as well.
The following code should work.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1) {
return 222;
} else if (indexPath.section == 2) {
return 80;
} else {
return 100;
}
}
I am new at iOS development.
I want to check if my table is empty. If it is, I want to :
Increase height of the first row and display "No new messages!"
OR
Get rid of the table and just display "No new messages" in the center of the page.
How would I do that?
(Let's assume you have an array from which you want to populate the table view. This is a pretty standard way for populating table views. Let's call this theoretical array dataArr.)
In your data source:
- (NSUInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSUInteger)section
{
if ([dataArr count] == 0) {
// empty table
return 1;
}
return [dataArr count];
}
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)ip
{
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:#"someCellID"];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"someCellID"] autorelease];
if ([dataArr count] == 0) {
// empty table
cell.textLabel.text = #"No new messages";
} else {
// configure as normally
}
return cell;
}
In your delegate:
- (CGFloat)tableView:(UITableView *)tv heightForRowAtIndexPath:(NSIndexPath *)ip
{
if ([dataArr count] == 0) {
// empty table
return 88.0f; // 2 times the normal height
}
// else return the normal height:
return 44.0f;
}
I suppose you have an array of messages you are attempting to display
You can define custom height for cells with the function
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (messages.count == 0)
return 80;
else
return 44;
}
and then, when you are creating the cells: (make sure the "no new messages" cell has a different cell identifier than the regular cells, so that your cell re-use won't mess things up)
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (messages.count == 0) {
// create the "No New Messages" cell
}
else {
// create regular cells
}
}
This should help:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([tableView numberOfRowsInSection:1] == 0) {
return 200;//some other height
}else{
return 44;
}
}
Basically you want to check against your data source to see if you have no messages in the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath and - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
For example:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([data count] == 0) return 100;
else return 44;
}