Is there any way to hide "-" (Delete) button while editing UITableView - ios

On my iphone app, I have a UITableView in edit mode, where user is allowed only to reorder the rows no delete permission is given.
So is there any way where I can hide "-" red button from TableView. Please let me know.
Thanks

Here is my complete solution, without indentation (0left align) of the cell!
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleNone;
}
- (BOOL)tableView:(UITableView *)tableview shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
- (BOOL)tableView:(UITableView *)tableview canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}

Swift 5 equivalent to accepted answer with just the needed funcs:
extension YourViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .none
}
}

This stops indentation:
- (BOOL)tableView:(UITableView *)tableview shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}

I faced a similar problem where I wanted custom checkboxes to appear in Edit mode but not the '(-)' delete button.
Stefan's answer steered me in the correct direction.
I created a toggle button and added it as an editingAccessoryView to the Cell and wired it to a method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
....
// Configure the cell...
UIButton *checkBoxButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 40.0f, 32.0f)];
[checkBoxButton setTitle:#"O" forState:UIControlStateNormal];
[checkBoxButton setTitle:#"√" forState:UIControlStateSelected];
[checkBoxButton addTarget:self action:#selector(checkBoxButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
cell.editingAccessoryType = UITableViewCellAccessoryCheckmark;
cell.editingAccessoryView = checkBoxButton;
return cell;
}
- (void)checkBoxButtonPressed:(UIButton *)sender {
sender.selected = !sender.selected;
}
Implemented these delegate methods
- (BOOL)tableView:(UITableView *)tableview shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleNone;
}

When you only want to hide the (-) dot while editing but you may want to keep the deleting functionality for the users you implement it like so in your UITableViewDelegate protocol conforming class
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.editing) return UITableViewCellEditingStyleNone;
return UITableViewCellEditingStyleDelete;
}

Related

UiTableViewCell is not displaying in Storybord

UiTableViewCell is not displaying in Storybord,
UiTableViewCell is not displaying in Storybord,UITableViewCell is not displaying in Storybord can any one help me Thanks in advance
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 50;
}
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 100;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ContactsCell";
ContactsCell *cell = (ContactsCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
cell = [[ContactsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.accessoryType=UITableViewCellAccessoryCheckmark;
cell.accessoryType=UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
Have you set Delegate and DataSource of you UITableView?
Using,
[self.IByourTableView setDelegate:self];
[self.IByourTableView setDataSource:self];
Update #1: For answer comment(ie: Open ChatViewController),
for that use delegate method of UITableView
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var storyBoardName = "Main"
var storyBoard:UIStoryboard?
storyBoard = UIStoryboard(name: storyBoardName, bundle: nil)
var gotoViewController: UIViewController? = storyBoard?.instantiateViewControllerWithIdentifier("YourViewControllerIdentifier") as? UIViewController
navigationController?.pushViewController(gotoViewController!, animated: true)
}
Note:Go to Story board and give Identifier to your ChatViewController
you wrote nothing to display in table
in cellforrow at indexpath add below line
cell.textlable.text=#"add something";
or replace your cellforrowatindexpath with below code
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ContactsCell";
ContactsCell *cell = (ContactsCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
cell = [[ContactsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.accessoryType=UITableViewCellAccessoryCheckmark;
cell.accessoryType=UITableViewCellAccessoryDetailDisclosureButton;
cell.textlable.text=#"add something";
return cell;
}
Do you know that you can't make UITableViewCell appear in storyboard by writing code? All the code you wrote will only display in the device.
You want UITableViewCell to appear in storyboard then you need to open storyboard and start adding and editing your uitableviewcell not by writing code.

UITableView commitEditingStyle only on particular cases

Is it possible to make editable the UITableView by adding the commitEditingStyle method only under certain circumstances ?
I have a controller.m/.h file that is doing stuff for 3 differents storyboards viewcontrollers. I want only 2 of the 3 to be able to commitEditingStyle. I can distinguish them using the self.restorationIdentifier.
you can check tableview tag..
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableview.tag==1 || tableview.tag==2)
return UITableViewCellEditingStyleDelete;
return UITableViewCellEditingStyleNone;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
//here your code
}
}
public override UITableViewCellEditingStyle EditingStyleForRow(UITableView tableView, NSIndexPath indexPath)
{
//here we show and hide the delete for particular row
if (indexPath.Row ==1)
{
return UITableViewCellEditingStyle.Delete;
}
else {
return UITableViewCellEditingStyle.None;
}
}
public override void CommitEditingStyle(UITableView tableView, UITableViewCellEditingStyle editingStyle, NSIndexPath indexPath)
{
if (editingStyle == UITableViewCellEditingStyle.Delete)
{
//here we handle delete button action of the tableview
}
}
Well, seems that I had simply to subclass and add the commitEditingStyle on the subclass. Then change the class in the storyboard to the subclass and that's all.

Removing UITableViewCell Selection

Currently I'm overriding the standard UITableViewSelectionStyle by using UITableViewSelectionStyleNone and then changing the color the cell based on delegate methods:
- (void)tableView:(UITableView *)tableView
didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor yellowColor]];
}
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor whiteColor]];
}
- (void)tableView:(UITableView *)tableView
didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"indexpath: %i",indexPath.row);
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor whiteColor]];
}
- (void)tableView:(UITableView *)tableView
didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor whiteColor]];
}
This almost works except that whenever I highlight a cell and then drag my finger off of it without actually selecting it, the color doesn't change to white...if I set it to [UIColor RedColor] it works perfeclty. Why is this...
Edit:
Somehow when I print out the indexPath.row after didUnhlightRowAtIndexPath I get "indexpath: 2147483647" from my NSLog
You could try:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
if you just want the highlight to go away after selecting a cell. Unless I misunderstand your question.
You can also try this
tableView.allowsSelection = NO;
another way of doing this
cell.selectionStyle = UITableViewCellSelectionStyleNone;
one more
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
You can also do it from the storyboard. Select the tableViewCell and under Attributes Inspector you can choose Selection > None
Here is a Swift 2 version
if let indexPaths = self.tableView.indexPathsForSelectedRows {
for indexPath in indexPaths {
self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
Unselect selected row(s). You do not even need to know which one it is.
tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
By maintaing a local instance of my indexPath, I was able to find the last selected cell and change its color to whitecolor. Seems really annoying that I have to maintain state myself, but it is what it is...
How about doing this with an extension?
import UIKit
extension UITableView {
func removeRowSelections() {
self.indexPathsForSelectedRows?.forEach {
self.deselectRow(at: $0, animated: true)
}
}
}
Usage:
tableView.removeRowSelections()
Simplest solution that worked for me (Swift 4.2)
(if you still want table view's row to be selectable)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let index = self.tableView.indexPathForSelectedRow{
self.tableView.deselectRow(at: index, animated: true)
}
}

How to set User Interaction enabled in UITableView cell

I am using UITableview(grouped). I have disabled the user interaction in xib. But, I want to enable the interaction for one cell. How can I enable this? I have used [cell setUserInteractionEnabled:yes] which is not working. -tableView didselectrowindexpath is not getting called. Can any one suggest me. Thanks in advance
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//Configure the cell
if (indexPath.row == yourcell)
cell.userInteractionEnabled = YES;
}
Hope,this will help you
enable the user interaction in Xib.
add
if(indexPath.row != YOUR ROW NO)
cell.userInteractionEnabled = NO;
in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
hope it helps. happy coding :)
// To enable or disable user Interaction in particular Cell , you can try below code
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//i have used guard statment for creating object of class you can also use if you wish
guard let createCell = tableView.dequeueReusableCell(withIdentifier: "Create") as? CreateProfileCell else {
return CreateProfileCell()
}
//now You can enable or disable user interaction in cell you want as i did below
switch indexPath.row {
case 0:
createCell.isUserInteractionEnabled = false . // false to disable interaction
case 1:
createCell.isUserInteractionEnabled = true // true to enable interaction
case 2:
createCell.isUserInteractionEnabled = false
default:
print("try again")
}
return createCell
}

UITableView: how to disable dragging of items to a specific row?

I have a UITableView with draggable rows and I can add/remove items. The datasource is a NSMutableArray.
Now, if I move the row with "Add new functionality" the app crashes because the dataSource is smaller since such row has not been added yet.
So I've modified this code:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row >= [dataList count]) return NO;
return YES;
}
And now I can't move it anymore. However I can still move the other rows after such row and consequently the code crashes.
How can I solve this ? Is there a way to disable the dragging "to" specific rows and not only from ?
thanks
This is exactly what the UITableViewDelegate method
-tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:
is for. Will it suit your purposes? Here's the documentation.
The previous answers and the documentation (see this and this, as mentioned in the other answers) are helpful but incomplete. I needed:
examples
to know what to do if the proposed move is not okay
Without further ado, here are some
Examples
Accept all moves
- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
return proposedDestinationIndexPath;
}
Reject all moves, returning the row to its initial position
- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
return sourceIndexPath;
}
Reject some moves, returning any rejected row to its initial position
- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if (... some condition ...) {
return sourceIndexPath;
}
return proposedDestinationIndexPath;
}
How to make last row fix:
- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
// get number of objects
NSUInteger numberOfObjects = [[[BNRItemStore sharedStore] allItems] count];
if ( (proposedDestinationIndexPath.row+1==numberOfObjects) || (sourceIndexPath.row+1==numberOfObjects) ) {
NSLog(#"HERE");
return sourceIndexPath;
}
else{
NSLog(#"count=%d %d", [[[BNRItemStore sharedStore] allItems] count], proposedDestinationIndexPath.row);
return proposedDestinationIndexPath;
}
}
Following is the example to restrict drag and drop to 0th index of 1st section UICollectionView:
func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
if session.localDragSession != nil {
// Restricts dropping to 0th index
if destinationIndexPath?.row == 0 {
return UICollectionViewDropProposal(operation: .forbidden)
}
if collectionView.hasActiveDrag {
return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
} else {
return UICollectionViewDropProposal(operation: .copy, intent: .insertAtDestinationIndexPath)
}
}
}
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
// Prevents dragging item from 0th index
if indexPath.row == 0 {
return [UIDragItem]() // Prevents dragging item from 0th index
}
let item = self.yourArray[indexPath.row]
let itemProvider = NSItemProvider(object: item)
let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = item
return [dragItem]
}
Following is the working solution for disable row from moving.
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
if indexPath.row == 0{//specify your indexpath row here....
return false
}else{
return true
}
}

Resources