objective-c UITableViewCell 附件类型在点击时选中并设置其他未选中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1750753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 22:30:46  来源:igfitidea点击:

UITableViewCell Accessory Type Checked on Tap & Set other unchecked

iphoneobjective-cxcodeuitableview

提问by Sagar R. Kothari

I am confused a little bit about settings table view cell accessories.

我对设置表格视图单元格附件有点困惑。

I have fixed two sections in my table

我在我的表中固定了两个部分

  • Home
  • Office
  • 办公室

What I want is as follow....

我想要的是如下......

  • When User tap any of the cell
  • Cell gets selected &
    • I want to set checked (set uitableviewcell accessory type -checked of tapped cell )
  • And also all other cell's accessory type now should set to
    • uitable view cell accessory type none
  • 当用户点击任何单元格时
  • 单元格被选中 &
    • 我想设置为选中(设置 uitableviewcell 附件类型 - 已选中的点击单元格)
  • 并且所有其他单元格的附件类型现在应该设置为
    • 适用的观察单元附件类型 无

I have tried following code. But I found that indexpath.row & indexpath.section is readonly properties.

我试过以下代码。但我发现 indexpath.row & indexpath.section 是只读属性。

// Override to support row selection in the table view.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {    
    [tblProfileView deselectRowAtIndexPath:indexPath animated:YES];
    int i,max;
    UITableViewCell *x; NSIndexPath *tt;

    for(i=0;i<[tblProfileView numberOfRowsInSection:0];i++)
    {
        tt.row=i; tt.section=0;
        x=[tblProfileView cellForRowAtIndexPath:];
        [x setAccessoryType:UITableViewCellAccessoryNone];
    }
    for(i=0;i<[tblProfileView numberOfRowsInSection:1];i++)
    {
        tt.row=i; tt.section=1;
        x=[tblProfileView cellForRowAtIndexPath:tt];
        [x setAccessoryType:UITableViewCellAccessoryNone];
    }

    x=[tblProfileView cellForRowAtIndexPath:indexPath];
    [x setAccessoryType:UITableViewCellAccessoryCheckmark];
    // Navigation logic may go here -- for example, create and push another view controller.
    // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil];
    // [self.navigationController pushViewController:anotherViewController animated:YES];
    // [anotherViewController release];
}

回答by gerry3

I would keep track of the datathat should be checked and change the cell in tableView:didSelectRowAtIndexPath: and update which data is checked in tableView:cellForRowAtIndexPath: like this:

我会跟踪应该检查的数据并更改 tableView:didSelectRowAtIndexPath: 中的单元格并更新 tableView:cellForRowAtIndexPath: 中检查的数据:像这样:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // do usual stuff here including getting the cell

    // determine the data from the IndexPath.row

    if (data == self.checkedData)
    {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // determine the selected data from the IndexPath.row

    if (data != self.checkedData) {
       self.checkedData = data;
    }

    [tableView reloadData];
}

回答by palaniraja

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];

    if (newCell.accessoryType == UITableViewCellAccessoryNone) {
        newCell.accessoryType = UITableViewCellAccessoryCheckmark;
    }else {
        newCell.accessoryType = UITableViewCellAccessoryNone;
    }


}

also you need to remove the checkmark accessory on cellForRowAtIndexPath

您还需要删除 cellForRowAtIndexPath 上的复选标记附件

if ([selectedOptionsArray indexOfObject:cell.textLabel.text] != NSNotFound) {
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else{
    cell.accessoryType = UITableViewCellAccessoryNone;
}

回答by iKushal

Declare one int variable named prevand implement this method:-

声明一个名为的 int 变量prev并实现此方法:-

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

 UITableViewCell *cell =[tableView cellForRowAtIndexPath:indexPath];

   if (cell.accessoryType==UITableViewCellAccessoryNone) 
   {
      cell.accessoryType=UITableViewCellAccessoryCheckmark;
      if (prev!=indexPath.row) {
         cell=[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:prev inSection:0]];
         cell.accessoryType=UITableViewCellAccessoryNone;
         prev=indexPath.row;
     }

 }
 else{
     cell.accessoryType=UITableViewCellAccessoryNone;
 }
}

回答by Prasanna

A shortest and easiest way to implement logic for checkmark in selected row only.....

仅在选定行中实现复选标记逻辑的最短和最简单的方法.....



1.Create a global object of NSIndexPath..

1.创建一个NSIndexPath的全局对象..

selectedIndexPathForCheckMark= [[NSIndexPath alloc] init];

2.In didSelectRowAtIndexPath..

2.在 didSelectRowAtIndexPath..

//Assiging selected indexPath to the declared object

//将选定的indexPath分配给声明的对象

selectedIndexPathForCheckMark = indexPath;  
[tableView reloadData];

3.in cellForRowAtIndexPath..

3.在 cellForRowAtIndexPath 中..

if ([selectedIndexPathForCheckMark isEqual:indexPath]) {
    [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}else {
    //setAccessoryType None if not get the selected indexPath
    [cell setAccessoryType:UITableViewCellAccessoryNone];
}

回答by Beau Nouvelle

Here's how I do it with static cells, and bypassing cellForRow

这是我如何使用静态单元格并绕过 cellForRow

Create a var that stores the location of the "checked" cell.

创建一个存储“选中”单元格位置的变量。

 NSInteger _checkedCell;

Then just implement willDisplayCelland didSelectRowmethods like this.

然后只需实现willDisplayCell和这样的didSelectRow方法。

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (_checkedCell == indexPath.row) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    _checkedCell = indexPath.row;
    [self.tableView reloadData];
}

回答by Nacho Mezzadra

I known this question is quite old, but here is the Swift version based on Blackberry's response (which I've voted up by the way)

我知道这个问题已经很老了,但这里是基于黑莓回应的 Swift 版本(顺便说一句,我已经投票赞成)

import UIKit

class PlacesViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource {

    var placesArray = NSMutableArray()
    
    var previousCheckedIndex = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.placesArray.addObject("Tandil")
        self.placesArray.addObject("Balcarce")
        self.placesArray.addObject("Mar del Plata")
        
        self.tableView.rowHeight = UITableViewAutomaticDimension
    }

    
    
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.placesArray.count
    }
    
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        
        var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell

        cell.textLabel?.text = self.placesArray.objectAtIndex(indexPath.row) as? String
        

        return cell
    }
    
    
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        if (indexPath.row != previousCheckedIndex) {
            var cell: UITableViewCell = self.tableView.cellForRowAtIndexPath(indexPath)!
            if (cell.accessoryType == UITableViewCellAccessoryType.None) {
                cell.accessoryType = UITableViewCellAccessoryType.Checkmark
                if (previousCheckedIndex != indexPath.row) {
                    cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: previousCheckedIndex, inSection: 0))!
                    cell.accessoryType = UITableViewCellAccessoryType.None
                    previousCheckedIndex = indexPath.row
                }
            } else {
                cell.accessoryType = UITableViewCellAccessoryType.None
            }
        
            tableView.reloadData()
        }
    }
}

回答by Pablo Ruan

In Swift 2.0 using custom accessoryView uitableviewcell with swift

在 Swift 2.0 中快速使用自定义附件视图 uitableviewcell

1o Creating Globar var IndexPath

1o 创建 Globar var IndexPath

var indexSelected = NSIndexPath()

2o In didSelectRowAtIndexPath

2o 在 didSelectRowAtIndexPath

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        indexSelected = indexPath
        TB_Lojas.reloadData()
    }

3o in cellForRowAtIndexPath:

3o 在 cellForRowAtIndexPath 中:

if SelectedIndexPath == indexPath {
                let img = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
                img.image = UIImage(named: "check")
                cell.accessoryView = img
            }else{
                let img = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
                img.image = UIImage(named: "uncheck")
                cell.accessoryView = img
            }
}

回答by Derek Hewitt

Considering you only want to maintain a single selection, and if you have a custom UITableViewCell, I would recommend the following.

考虑到您只想维护一个选择,并且如果您有自定义UITableViewCell,我会推荐以下内容。

In your UITableViewController

在你的 UITableViewController

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    //... 
    let data = dataArray[indexPath.row]
    if data.isSelected {
        tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: .None)
    }
    //...

    return cell
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let data = dataArray[indexPath.row]
    data.isSelected = true
    let cell = tableView.cellForRowAtIndexPath(indexPath)
    cell?.setSelected(true, animated: true)
}

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    let data = dataArray[indexPath.row]
    data.isSelected = false
    let cell = tableView.cellForRowAtIndexPath(indexPath)
    cell?.setSelected(false, animated: true)
}

In the custom UITableViewCell

在习俗 UITableViewCell

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
    self.accessoryType = .None
    if selected {
        self.accessoryType = .Checkmark
    }
}

As long as allowsMultipleSelectionis not enabled, it will automatically handle deselecting other cells when a new one is selected. If allowMultipleSelectionis enabled, then it will work as well, except you will just need to tap again to deselect.

只要allowsMultipleSelection未启用,它会在选择新单元格时自动处理取消选择其他单元格。如果allowMultipleSelection已启用,那么它也可以正常工作,除非您只需要再次点击以取消选择。

回答by Bart van Kuik

BlackBerry's answer in Swift 3. UITableView with standard cells, selecting 0 or 1 cells.

黑莓在 Swift 3 中的回答。带有标准单元格的 UITableView,选择 0 或 1 个单元格。

private var previousSelection = NSIndexPath()

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    let cell = tableView.cellForRow(at: indexPath)!
    if cell.accessoryType == .none {
        cell.accessoryType = .checkmark
        selection = indexPath

        if previousSelection == IndexPath() {
            previousSelection = indexPath
        } else if previousSelection != indexPath {
            let previousCell = tableView.cellForRow(at: previousSelection)
            previousCell?.accessoryType = .none
            previousSelection = indexPath
        }
    } else if cell.accessoryType == .checkmark {
        cell.accessoryType = .none
        selection = IndexPath()
    }

}