Ich bin ein iOS-Neuling. Ich möchte meiner UITableViewCell
ein Häkchen setzen, wenn sie ausgewählt ist. Das Häkchen sollte entfernt werden, wenn eine andere Zeile ausgewählt wird. Wie würde ich das machen?
Verwenden Sie nicht [tableview reloadData];
// einen Hammer.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
In Ihrer UITableViewDatasource-Methode:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil )
{
cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if ([indexPath compare:self.lastIndexPath] == NSOrderedSame)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
// UITableView Delegate Method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.lastIndexPath = indexPath;
[tableView reloadData];
}
Und lastIndexPath ist eine property(strong) NSIndexPath* lastIndexPath;
Ich fand, dass das erneute Laden der Daten die Deaktivierungsanimation auf eine hässliche Weise unterbricht.
Diese Swift-Implementierung fügt die Zeile sauber hinzu und entfernt die Markierung:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if self.lastSelection != nil {
self.myTableView.cellForRowAtIndexPath(self.lastSelection)?.accessoryType = .None
}
self.myTableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark
self.lastSelection = indexPath
self.myTableView.deselectRowAtIndexPath(indexPath, animated: true)
}
wobei lastSelection
als var lastSelection: NSIndexPath!
deklariert ist
Keine zusätzliche Aktivität in cellForRowAtIndexPath
erforderlich. Sollte in Obj-C nicht schwer zu replizieren sein.
So setzen Sie ein Häkchen:
UITableViewCell *cell = ...;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
So wählen Sie eine Zelle aus oder ab,
[cell setSelected:TRUE animated:TRUE]; // select
[cell setSelected:FALSE animated:TRUE]; // deselect
Um die Auswahl der vorherigen Zelle aufzuheben, verwenden Sie ein NSIndexPath * lastSelected-Feld, um die letzte ausgewählte Zelle zu verfolgen:
- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
if (self.lastSelected==indexPath) return; // nothing to do
// deselect old
UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected];
old.accessoryType = UITableViewCellAccessoryNone;
[old setSelected:FALSE animated:TRUE];
// select new
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[cell setSelected:TRUE animated:TRUE];
// keep track of the last selected cell
self.lastSelected = indexPath;
}
extension ViewController : UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = dataArray[indexPath.row]
if selectedData.contains(dataArray[indexPath.row]) {
cell.accessoryType = .checkmark
}else{
cell.accessoryType = .none
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if selectedData.contains(dataArray[indexPath.row]) {
selectedData.removeLast()
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}else {
selectedData.removeAll()
selectedData.append(dataArray[indexPath.row])
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
print(selectedData)
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
}
basierend auf der dataArray-Tabellenansicht .. In ähnlicher Weise nahm ich ein leeres Array und jedes Mal, wenn der Benutzer auf eine Zelle tippt, basierend auf dem indexValue von dataArray, habe ich dieses Objekt in selectedDataArray gespeichert
Wie für die Frage ist es wie ... Eine Frage hat mehrere Optionen (Antworten), aber am Ende wird nur eine oder keine Antwort ein Ergebnis sein
Ebenso sollte nur eine Zelle ein Häkchen anzeigen, und die verbleibenden Zellen sollten nicht ausgewählt sein. In einigen Fällen können Sie die Antwort abwählen. Ich hoffe, dies ist die beste Antwort auf diese Frage
Angenommen, Sie befinden sich in einer Klasse, die von UITableViewController
erbt, bewirkt den Trick in Swift 3:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Add a visual cue to indicate that the cell was selected.
self.tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
// Invoked so we can prepare for a change in selection.
// Remove previous selection, if any.
if let selectedIndex = self.tableView.indexPathForSelectedRow {
// Note: Programmatically deslecting does NOT invoke tableView(:didSelectRowAt:), so no risk of infinite loop.
self.tableView.deselectRow(at: selectedIndex, animated: false)
// Remove the visual selection indication.
self.tableView.cellForRow(at: selectedIndex)?.accessoryType = .none
}
return indexPath
}
Es ist besser, sich diesem Problem aus einer anderen Richtung zu stellen. Setzen Sie alle Arbeit auf interne UIKit-Mechanismen und verschieben Sie die Implementierung auf UITableViewCell:
@implementation MYTableViewCell
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
self.accessoryType = selected ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
}
- (void)prepareForReuse {
[super prepareForReuse];
self.accessoryType = UITableViewCellAccessoryNone;
}
@end
Die obigen Antworten funktionieren nicht, wenn Sie die Zelle für eine große Anzahl von Daten wiederverwenden. Beim Scrollen sehen Sie ein wiederholtes Häkchen. So vermeiden Sie die Verwendung der folgenden Schritte:
deklarieren Sie für Variable: var indexNumber: NSInteger = -1
Fügen Sie den folgenden Code in cellforRowAtIndexPath hinzu:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
if indexNumber == indexPath.row{
cell.accessoryType = .checkmark
}else{
cell.accessoryType = .none
}
}
Und in didselectAtIndexpath fügen Sie folgenden Code hinzu:
func tableView überschreiben (_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark
indexNumber = indexPath.row
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .none
}
kleiner Tippfehler
// deselect old
UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected];
cell.accessoryType = UITableViewCellAccessoryNone;
[cell setSelected:FALSE animated:TRUE];
sollte lesen
// deselect old
UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected];
old.accessoryType = UITableViewCellAccessoryNone;
[old setSelected:FALSE animated:TRUE];
und auch in der
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == [previouslySelected intValue])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
selectedIndex = indexPath;
[cell setSelected:YES animated:YES];
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
[cell setSelected:NO animated:YES];
}
}
dabei ist beforeSelected Ihr lokaler ivar usw. Wenn Sie einen ausgewählten Index neu laden, wird er auch deaktiviert, wenn Sie durch die möglichen Auswahlmöglichkeiten blättern.
Update Swift 4
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
Verwenden von Swift 4.2 und Swift 5 Arbeitscode des Häkchens für nur ausgewählte Zeilen in TableView
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
self.tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//print(self.coloursArray[indexPath.row])
self.tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
Rufen Sie einfach die didSelectRowAtIndexPath
-Methode auf, wenn Sie eine beliebige Zeile auswählen, um CheckMark anzeigen und Checkmarkierung auswählen, um CheckMark auszublenden.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:true];
NSLog(@"touch");
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
Wenn eine ausgewählte Zelle (mit dem Häkchen erneut ausgewählt) ausgewählt wird, entfernen Sie einfach die Auswahl.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
BOOL isSelected = ([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark);
if(isSelected){
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
[tableView deselectRowAtIndexPath:indexPath animated:YES]; //this won't trigger the didDeselectRowAtIndexPath, but it's always a good idea to remove the selection
}else{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath*)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
Bonus:
Verwenden Sie self.tableView.indexPathForSelectedRow
zum Ermitteln von indexPath für die ausgewählte Zelle
Swift 4 für den Fall, dass Sie brauchen.
var lastSelection: NSIndexPath!
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//CHECK MARK THE CELL
if self.lastSelection != nil {
self.tableView.cellForRow(at: self.lastSelection as IndexPath)?.accessoryType = .none
}
self.tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
self.lastSelection = indexPath as NSIndexPath
self.tableView.deselectRow(at: indexPath, animated: true)
}
Der oben erwähnte Code funktioniert nur mit der Einzelauswahl Dieser folgende Code wird sicherlich für Mehrfachauswahl funktionieren.
- (void)viewDidLoad {
arrSelectionStatus =[NSMutableArray array]; //arrSelectionStatus holds the cell selection status
for (int i=0; i<arrElements.count; i++) { //arrElements holds those elements which will be populated in tableview
[arrSelectionStatus addObject:[NSNumber numberWithBool:NO]];
}
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (cell==nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
cell.textLabel.text=[arrElements objectAtIndex:indexPath.row];
if ([[arrSelectionStatus objectAtIndex:indexPath.row] boolValue] == YES)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[arrSelectionStatus replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:YES]];
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
[arrSelectionStatus replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:NO]];
}