เป็นไปได้หรือไม่ที่จะรีเฟรช UITableViewCell เดียวใน UITableView


182

ฉันมีแบบกำหนดเองUITableViewโดยใช้UITableViewCells แต่ละUITableViewCellปุ่มมี 2 ปุ่ม การคลิกปุ่มเหล่านี้จะเป็นการเปลี่ยนภาพUIImageViewภายในเซลล์

เป็นไปได้ไหมที่จะรีเฟรชแต่ละเซลล์แยกกันเพื่อแสดงภาพใหม่? ความช่วยเหลือใด ๆ ที่ชื่นชม

คำตอบ:


323

เมื่อคุณมี indexPath ของเซลล์คุณสามารถทำสิ่งต่อไปนี้

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPathOfYourCell, nil] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates]; 

ใน Xcode 4.6 ขึ้นไป:

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[indexPathOfYourCell] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates]; 

คุณสามารถกำหนดสิ่งที่คุณชอบเป็นเอฟเฟกต์ภาพเคลื่อนไหวได้แน่นอน


4
วางตลาดที่นี่ แต่แน่นอนถ้าคุณเพิ่งรีเฟรชเซลล์เดียวที่คุณอาจต้องการใช้[NSArray arrayWithObject:]แทน
Leo Cassarani

57
นอกจากนี้ในสถานการณ์เช่นนี้beginUpdatesและendUpdatesไม่จำเป็น
kubi

2
OP ไม่ได้เคลื่อนไหวอะไรเลยดังนั้นไม่จำเป็นต้องโทรหา start / endupdates
kubi

2
ตราบใดที่วิธีการนั้นไม่ได้บอกว่าเลิกใช้แล้วในรุ่น Xcode สาธารณะครั้งล่าสุดเวอร์ชั่น iOS ทั้งหมดควรจะใช้ได้
Alejandro Iván

1
@Supertecnoboff จริง แต่ในบางจุดอาจถูกแทนที่หรือจะเปลี่ยนพฤติกรรมของมัน จะดีกว่าที่จะจัดการกับการเสื่อมราคาโดยเร็ว
Alejandro Iván

34

ฉันพยายามโทร-[UITableView cellForRowAtIndexPath:]แต่ก็ไม่ได้ผล แต่ตัวอย่างต่อไปนี้เหมาะสำหรับฉัน ฉันallocและสำหรับการจัดการหน่วยความจำแน่นreleaseNSArray

- (void)reloadRow0Section0 {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    NSArray *indexPaths = [[NSArray alloc] initWithObjects:indexPath, nil];
    [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
    [indexPaths release];
}

[indexPaths release] จำเป็นหรือไม่ ฉันคิดว่าคุณต้องการเพียงว่าถ้าคุณจัดสรรวัตถุด้วยตัวเอง
powerj1984

4
เขาจัดสรรอาเรย์ indexPaths แต่คำถามที่ดีกว่าคือเหตุผลที่เขาคิดว่า "การจัดการหน่วยความจำที่รัดกุม" เป็นสิ่งจำเป็น Autorelease จะทำงานได้อย่างสมบูรณ์แบบที่นี่
John Cromartie

22

สวิฟท์:

func updateCell(path:Int){
    let indexPath = NSIndexPath(forRow: path, inSection: 1)

    tableView.beginUpdates()
    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) //try other animations
    tableView.endUpdates()
}

จะเรียกวิธีนี้ได้ที่ไหน
Master AgentX

18

reloadRowsAtIndexPaths:ดี แต่ก็ยังจะบังคับให้UITableViewDelegateวิธีการยิง

วิธีที่ง่ายที่สุดที่ฉันสามารถจินตนาการได้คือ:

UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
[self configureCell:cell forIndexPath:indexPath];

มันเป็นสิ่งสำคัญที่จะก่อให้เกิดของconfigureCell:การดำเนินงานในหัวข้อหลักเป็นมันเคยชินทำงานในหัวข้อที่ไม่ใช่ UI (เรื่องเดียวกันกับreloadData/ reloadRowsAtIndexPaths:) บางครั้งการเพิ่ม:

dispatch_async(dispatch_get_main_queue(), ^
{
    [self configureCell:cell forIndexPath:indexPath];
});

นอกจากนี้ยังควรหลีกเลี่ยงงานที่จะต้องทำนอกมุมมองที่มองเห็นในปัจจุบัน:

BOOL cellIsVisible = [[self.tableView indexPathsForVisibleRows] indexOfObject:indexPath] != NSNotFound;
if (cellIsVisible)
{
    ....
}

ทำไมคุณไม่ต้องการให้ผู้ร่วมประชุมถูกเรียก?
kernix

นี่เป็นวิธีที่ดีที่สุดเนื่องจากไม่ได้บังคับให้มุมมองตารางเลื่อนไปตลอดทางจนถึงด้านบนซึ่งต่างกับ reloadRowsAtIndexPaths: หรือเมธอด reloadData
ZviBar

ฉันทำสิ่งนี้และจบลงด้วยการที่เซลล์ถูกรีไซเคิล
Traveller Man

16

หากคุณใช้ TableViewCells แบบกำหนดเองอยู่ทั่วไป

[self.tableView reloadData];    

ไม่ตอบคำถามนี้อย่างมีประสิทธิภาพเว้นแต่คุณจะออกจากมุมมองปัจจุบันและกลับมา คำตอบแรกไม่เหมือนกัน

หากต้องการโหลดเซลล์มุมมองตารางแรกของคุณอีกครั้งโดยไม่เปลี่ยนมุมมองให้ใช้รหัสต่อไปนี้:

//For iOS 5 and later
- (void)reloadTopCell {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    NSArray *indexPaths = [[NSArray alloc] initWithObjects:indexPath, nil];
    [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}

แทรกวิธีการรีเฟรชต่อไปนี้ซึ่งโทรไปยังวิธีการด้านบนเพื่อให้คุณสามารถโหลดซ้ำได้เฉพาะเซลล์ด้านบน (หรือมุมมองตารางทั้งหมดหากคุณต้องการ):

- (void)refresh:(UIRefreshControl *)refreshControl {
    //call to the method which will perform the function
    [self reloadTopCell];

    //finish refreshing 
    [refreshControl endRefreshing];
}

ตอนนี้คุณมีการเรียงลำดับที่ด้านในของคุณviewDidLoadเพิ่มต่อไปนี้:

//refresh table view
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];

[refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];

[self.tableView addSubview:refreshControl];

ตอนนี้คุณมีคุณสมบัติตารางรีเฟรชที่กำหนดเองที่จะโหลดเซลล์ด้านบนใหม่ หากต้องการโหลดทั้งตารางใหม่ให้เพิ่ม

[self.tableView reloadData]; กับวิธีการรีเฟรชใหม่ของคุณ

หากคุณต้องการโหลดข้อมูลใหม่ทุกครั้งที่คุณเปลี่ยนมุมมองให้ใช้วิธีการ:

//ensure that it reloads the table view data when switching to this view
- (void) viewWillAppear:(BOOL)animated {
    [self.tableView reloadData];
}


4

เพียงแค่อัปเดตคำตอบเหล่านี้เล็กน้อยด้วยไวยากรณ์ตัวอักษรใหม่ใน iOS 6 - คุณสามารถใช้ Paths = @ [indexPath] สำหรับวัตถุเดียวหรือ Paths = @ [indexPath1, indexPath2, ... ] สำหรับหลาย ๆ วัตถุ

โดยส่วนตัวแล้วฉันได้พบไวยากรณ์ที่แท้จริงของอาร์เรย์และพจนานุกรมที่มีประโยชน์อย่างมากและเป็นผู้ประหยัดครั้งใหญ่ มันง่ายกว่าที่จะอ่านสำหรับสิ่งหนึ่ง และมันไม่จำเป็นต้องมีศูนย์ในตอนท้ายของรายการหลายวัตถุใด ๆ ซึ่งเป็นแมลงปีกแข็งส่วนตัวอยู่เสมอ เราทุกคนมีกังหันลมเพื่อเอียงด้วยใช่ไหม ;-)

แค่คิดว่าฉันจะโยนมันลงไปในส่วนผสม หวังว่ามันจะช่วย


พูดว่า Greg ตัวอย่างของไวยากรณ์ที่นั่นโปรดคืออะไร ขอบคุณ!
Fattie

3

นี่คือส่วนขยาย UITableView ด้วย Swift 5:

import UIKit

extension UITableView
{    
    func updateRow(row: Int, section: Int = 0)
    {
        let indexPath = IndexPath(row: row, section: section)

        self.beginUpdates()
        self.reloadRows(at: [indexPath as IndexPath], with: UITableView.RowAnimation.automatic)
        self.endUpdates()
    }

}

โทรไปด้วย

self.tableView.updateRow(row: 1)

0

ฉันต้องการเซลล์อัพเกรด แต่ฉันต้องการปิดแป้นพิมพ์ ถ้าฉันใช้

let indexPath = NSIndexPath(forRow: path, inSection: 1)
tableView.beginUpdates()
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) //try other animations
tableView.endUpdates()

คีย์บอร์ดหายไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.