Ben bir iOS geliştirme acemisiyim. UITableViewCell
Seçildiğinde kendime bir onay işareti eklemek istiyorum . Başka bir satır seçildiğinde onay işareti kaldırılmalıdır. Bunu nasıl yaparım?
Yanıtlar:
[tableview reloadData];
Bir çekiç // kullanmayın .
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
UITableViewDatasource yönteminizde:
- (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];
}
Ve lastIndexPath bir property(strong) NSIndexPath* lastIndexPath;
Verileri yeniden yüklemenin, seçimi kaldırma animasyonunu çirkin bir şekilde kesintiye uğrattığını buldum.
Bu Swift uygulaması, onay işaretlerini temiz bir şekilde ekler / kaldırır ve satırın seçimini kaldırır:
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)
}
nerede lastSelection
ilan edilirvar lastSelection: NSIndexPath!
Ekstra aktiviteye cellForRowAtIndexPath
gerek yok. Obj-C'de kopyalamak zor olmamalı.
Bir onay işareti koymak için:
UITableViewCell *cell = ...;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
Bir hücre seçmek / seçimini kaldırmak için:
[cell setSelected:TRUE animated:TRUE]; // select
[cell setSelected:FALSE animated:TRUE]; // deselect
Önceki hücrenin seçimini kaldırmak için, son seçilen hücreyi izlemek üzere NSIndexPath * lastSelected ivar kullanın:
- (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;
}
Swift 4'ü güncelleyin
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
}
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
}
}
dataArray tablo görünümüne dayalı olarak oluşturuldu .. benzer şekilde, boş bir dizi aldım ve kullanıcı bir hücreye her dokunduğunda, dataArray'deki indexValue değerine göre o nesneyi selectedDataArray'de depoladım
Soruya gelince ... Bir sorunun birden fazla seçeneği vardır (Cevaplar), Ama sonunda sadece bir cevap veya hiçbir cevap bir sonuç olacaktır
Aynı şekilde, yalnızca bir hücre onay işaretini göstermeli ve kalan hücreler seçili olmamalıdır ... bazı durumlarda cevabınızın seçimini kaldırabilirsiniz ... Umarım bu soruya en iyi cevap budur
Aksesuarı özel UITableViewCell uygulamanızda ayarlamanın daha temiz olduğunu düşünüyorum. Hızlı olarak, kullandım:
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
accessoryType = selected ? .checkmark : .none
}
Swift 4.2 ve swift 5 TableView'da yalnızca seçilen satır için onay işaretinin çalışma kodu
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
}
Miras alan bir sınıfta olduğunuzu varsayarsak UITableViewController
, bu Swift 3'teki hile yapar:
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
}
küçük yazım hatası
// deselect old
UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected];
cell.accessoryType = UITableViewCellAccessoryNone;
[cell setSelected:FALSE animated:TRUE];
okumalı
// deselect old
UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected];
old.accessoryType = UITableViewCellAccessoryNone;
[old setSelected:FALSE animated:TRUE];
ve ayrıca
- (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];
}
}
nerede previouslySelected vb yerel ivar olduğunu şekilde bu size olası seçenekler aracılığıyla fiske zaman da seçilmemiş olur Seçilen indeksi yeniden eğer.
Hücreyi çok sayıda veri için yeniden kullandıysanız, yukarıdaki yanıtlar işe yaramaz. Kaydırmada, tekrarlanan onay işaretlerini görebilirsiniz. Aşağıdaki adımları kullanmaktan kaçınmak için:
değişken üzerinde bildirim: var indexNumber: NSInteger = -1
CellforRowAtIndexPath'e aşağıdaki kodu ekleyin:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
if indexNumber == indexPath.row{
cell.accessoryType = .checkmark
}else{
cell.accessoryType = .none
}
}
Ve didselectAtIndexpath içinde aşağıdaki kodu ekleyin:
override func tableView (_ 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
}
Bu problemle başka bir yönden yüzleşmek daha iyidir. Tüm çalışmaları dahili UIKit mekanizmalarına koyun ve uygulamayı UITableViewCell'e taşıyın:
@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
didSelectRowAtIndexPath
Onay İşaretini Göster için herhangi bir satırı seçtiğinizde Yöntemi Çağırın ve Onay İşaretini gizlemek için onay işareti satırını seçin.
- (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;
}
}
İhtiyacınız olması durumunda swift 4.
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)
}
Bunu yapmanın iki yolu var. biri çoklu seçim içermiyor ve diğeri çoklu seçim içeriyor.
// Table View Controller -- without Multiple Selection
// Step 1
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if(tableView.cellForRow(at: indexPath)?.imageView?.image == UIImage(systemName:"checkmark.circle")) {
tableView.cellForRow(at: indexPath)?.imageView?.image = UIImage(systemName:"circle")
} else {
tableView.cellForRow(at: indexPath)?.imageView?.image = UIImage(systemName:"checkmark.circle")
}
}
//Step 2
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = employeeValues[indexPath.row]
cell.imageView?.image = UIImage(systemName:"circle")
return cell
}
// Table View Controller -- with Multiple Selection
@IBOutlet var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.myTableView.allowsMultipleSelection = true
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = employeeValues[indexPath.row]
cell.imageView?.image = UIImage(systemName:"circle")
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// let cell = tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark
tableView.cellForRow(at: indexPath)?.imageView?.image = UIImage(systemName:"checkmark.circle")
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.imageView?.image = UIImage(systemName:"circle")
}
Yukarıda belirtilen kod yalnızca tek seçimle çalışır . Aşağıdaki kod kesinlikle birden çok seçim için çalışacaktır .
- (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]];
}
Seçili bir hücre (yeniden onay işaretli) seçildiğinde, seçimi kaldırmanız yeterlidir.
- (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:
self.tableView.indexPathForSelectedRow
Seçili hücre için indexPath'i algılamak için kullanın
// Check or Uncheck a cell
if let cell = tableView.cellForRow(at: indexPath) {
if cell.accessoryType == .checkmark {
cell.accessoryType = .none
} else {
cell.accessoryType = .checkmark
}
}