ฉันเป็นมือใหม่ในการพัฒนา iOS ฉันต้องการเพิ่มเครื่องหมายถูกUITableViewCell
เมื่อมีการเลือก ควรนำเครื่องหมายถูกออกเมื่อเลือกแถวอื่น ฉันจะทำอย่างไร
ฉันเป็นมือใหม่ในการพัฒนา iOS ฉันต้องการเพิ่มเครื่องหมายถูกUITableViewCell
เมื่อมีการเลือก ควรนำเครื่องหมายถูกออกเมื่อเลือกแถวอื่น ฉันจะทำอย่างไร
คำตอบ:
อย่าใช้[tableview reloadData];
// มันเป็นค้อน
- (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 ของคุณ:
- (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];
}
และ lastIndexPath คือไฟล์ property(strong) NSIndexPath* lastIndexPath;
ฉันพบว่าการโหลดข้อมูลซ้ำจะขัดขวางการยกเลิกการเลือกภาพเคลื่อนไหวในลักษณะที่น่าเกลียด
การใช้งาน Swift นี้เพิ่ม / ลบเครื่องหมายถูกทั้งหมดและยกเลิกการเลือกแถว:
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)
}
ที่lastSelection
ประกาศเป็นvar lastSelection: NSIndexPath!
ไม่cellForRowAtIndexPath
จำเป็นต้องทำกิจกรรมเพิ่มเติม ไม่ควรทำซ้ำใน Obj-C ได้ยาก
ในการตั้งค่าเครื่องหมายถูก:
UITableViewCell *cell = ...;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
ในการเลือก / ยกเลิกการเลือกเซลล์:
[cell setSelected:TRUE animated:TRUE]; // select
[cell setSelected:FALSE animated:TRUE]; // deselect
หากต้องการยกเลิกการเลือกเซลล์ก่อนหน้าให้ใช้ NSIndexPath * lastSelected ivar เพื่อติดตามเซลล์สุดท้ายที่เลือก:
- (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
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 ที่เกิดขึ้น .. ในทำนองเดียวกันฉันเอาอาร์เรย์ว่างและเมื่อใดก็ตามที่ผู้ใช้แตะที่เซลล์โดยยึดตาม indexValue จาก dataArray ฉันเก็บวัตถุนั้นไว้ใน selectedDataArray
สำหรับคำถามก็เช่น ... คำถามมีหลายตัวเลือก (คำตอบ) แต่สุดท้ายจะมีคำตอบเพียงคำตอบเดียวหรือไม่มีเลย
ในทำนองเดียวกันมีเพียงเซลล์เดียวเท่านั้นที่ควรแสดงเครื่องหมายถูกและควรยกเลิกการเลือกเซลล์ที่เหลือ ... บางกรณีคุณสามารถยกเลิกการเลือกคำตอบของคุณได้ ... ฉันหวังว่านี่จะเป็นคำตอบที่ดีที่สุดสำหรับคำถามนี้
ฉันคิดว่าการตั้งค่าอุปกรณ์เสริมภายในการใช้งาน UITableViewCell แบบกำหนดเองของคุณจะดีกว่า อย่างรวดเร็วฉันได้ใช้:
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 และ swift 5 รหัสการทำงานของเครื่องหมายถูกสำหรับเฉพาะแถวที่เลือกใน 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
}
สมมติว่าคุณอยู่ในคลาสที่สืบทอดมาUITableViewController
นี่เป็นเคล็ดลับใน 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
}
พิมพ์ผิดเล็ก ๆ
// deselect old
UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected];
cell.accessoryType = UITableViewCellAccessoryNone;
[cell setSelected:FALSE animated:TRUE];
ควรอ่าน
// deselect old
UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected];
old.accessoryType = UITableViewCellAccessoryNone;
[old setSelected:FALSE animated:TRUE];
และในไฟล์
- (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];
}
}
โดยที่ก่อนหน้านี้ Selected คือไอวาร์ในพื้นที่ของคุณเป็นต้นด้วยวิธีนี้หากคุณโหลดซ้ำด้วยดัชนีที่เลือกระบบจะยกเลิกการเลือกเมื่อคุณปัดผ่านการเลือกที่เป็นไปได้
คำตอบข้างต้นใช้ไม่ได้หากคุณใช้เซลล์ซ้ำสำหรับข้อมูลจำนวนมาก ในการเลื่อนคุณจะเห็นเครื่องหมายถูกซ้ำ เพื่อหลีกเลี่ยงการใช้ขั้นตอนด้านล่าง:
ประกาศตัวแปร: var indexNumber: NSInteger = -1
เพิ่มโค้ดด้านล่างใน cellforRowAtIndexPath:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
if indexNumber == indexPath.row{
cell.accessoryType = .checkmark
}else{
cell.accessoryType = .none
}
}
และใน didselectAtIndexpath เพิ่มโค้ดด้านล่าง:
แทนที่ 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
}
จะดีกว่าที่จะเผชิญกับปัญหานี้จากทิศทางอื่น วางงานทั้งหมดในกลไก UIKit ภายในและย้ายการใช้งานไปยัง 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
Just Call didSelectRowAtIndexPath
Method เมื่อเลือกแถวใดก็ได้เพื่อแสดง CheckMark และเลือกแถวเครื่องหมายถูกเพื่อซ่อน CheckMark
- (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;
}
}
รวดเร็ว 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)
}
มีสองวิธีที่คุณสามารถทำได้ หนึ่งไม่มีการเลือกหลายรายการและอีกรายการหนึ่งมีหลายตัวเลือก
// 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")
}
รหัสกล่าวถึงบนใช้งานได้เฉพาะกับตัวเลือกเดียวสิ่งอำนวยรหัสต่อไปนี้ก็จะทำงานให้เลือกหลาย
- (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]];
}
เมื่อเซลล์ที่เลือก (ที่มีเครื่องหมายถูกเลือกอีกครั้ง) ให้ลบส่วนที่เลือกออก
- (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;
}
โบนัส:
ใช้self.tableView.indexPathForSelectedRow
สำหรับตรวจหา indexPath สำหรับเซลล์ที่เลือก
// Check or Uncheck a cell
if let cell = tableView.cellForRow(at: indexPath) {
if cell.accessoryType == .checkmark {
cell.accessoryType = .none
} else {
cell.accessoryType = .checkmark
}
}