kopírování UITableViewCell

hlasů
7

Čtu buňku tabulky vlastní v tableView:cellForRowAtIndexPath:z nib souboru. To funguje skvěle hodí pro mé účely, kromě toho, že je docela pomalý.

Teď vím, že správná věc dělat v dlouhodobém horizontu je vytvořit buňku zcela v kódu a používat jednotný názor, a tak dále. Ale to je prototyp, a já nechci, aby to dát hodně úsilí do toho.

Pro tuto chvíli, byl bych rád, kdyby mi četl hrot pouze jednou UIViewControllerpodtřídy, pak tableView:cellForRowAtIndexPath:dělal kopie toho. Můj předpoklad je, že kopírování by být rychlejší než čtení hrot.

Tady je to, co mám použít k načtení hrotu, které jsem volat z viewDidLoad:(a retainpo něm)

-(id)loadFromNamed:(NSString*)name {
    NSArray *objectsInNib = [[NSBundle mainBundle] loadNibNamed:name
                                                          owner:self
                                                        options:nil];
    assert( objectsInNib.count == 1 );
    return [objectsInNib objectAtIndex:0];
}

Vše je dobré tak daleko. Ale otázka zní: Jak mohu zkopírovat to pořád dokola? Je to vůbec možné?

Zkoušel jsem [_cachedObject copy]i [_cachedObject mutableCopy], ale UITableViewCellnepodporuje buď kopie protokolu.

Mám-li, můžu jen říct jim, aby ignorovat rychlost, dokud jsem připraven na odstranění hrotu úplně, ale raději bych si to jít trochu rychleji, když je tu low-visící ovoce zde.

Nějaké nápady?

Položena 20/02/2009 v 21:43
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
8

Myslím, že zvládání buňky tabulky mohou být použity společně s dequeuing mechanismem, který umožní vytvořit buňce jednou (z hrotu nebo programově, nebo jak se automaticky načtena z jiných hrotu, a dává jako výstup v IB), a pak klonovat, nebo dequeue jej když je potřeba.

UITableViewCell neodpovídá NSCopying protokolu, ale podporuje a klíče archivaci / rozbalování mechanismus, takže může být použit pro klonování.

„Na odpověď na bázi ? Jak duplikovat UIButton v Objective C “ moje metoda zdroj dat delegát vypadá takto:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellID = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellID];

    if (!cell) {
        NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.tableViewCell];
        cell = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
    }

    // ... config ...

    return cell;
}

A v mém případě self.tableViewCell je buňka, která byla vložena jednou z nib souboru náhledu.

Nemám zkouší, co bude rychlejší: „archiv + Vyjmout z archivu“ klonovat nebo „load nib soubor + Vyjmout z archivu“, který rámec bude dělat v případě -loadNibNamed: Majitel: možností: jsem použil tuto metodu pouze s úvahami pohodlí, ale dobré šance, že bude operační paměti vs souborové operace být rychlejší.

EDIT: Vypadá to není tak jednoduché, jak se na první pohled zdálo. Jako UIImage není v souladu s NSCoding buňky s nakonfigurovaných UIImageViews nelze jen kopírovat bez dodatečného kódu. Jo, kopírování celý obraz rozhodně není dobré praxe, na zdraví Apple pro spárování to.

Odpovězeno 17/03/2011 v 13:00
zdroj uživatelem

hlasů
6

Použití buněk klonování integrována do zobrazení tabulky. Apple věděl generování hodně buněk tabulky byl pomalý. Podívejte se na dokumenty pro tuto metodu:

- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier

Jednou jsi vytvořit buňku, pak jako nové buňky jsou žádáni, používat tuto metodu pro klonování stávající buňky. Pak stačí změnit to, co je třeba změnit o nové buňky a vrátit objekt buněk.

Také podívejte se na tabulku pohledu realted ukázkový kód poskytnutý společností Apple, který používá tuto metodu a ukáže správnou cestu. Skutečnost, váš mobilní byl vložen z hrotu by měla nevadí vůbec.


Minor upřesnění: Nemyslím si, že výše uvedené metody klonování buněk pro vás. Namísto toho se buňky objekt, které posune mimo obrazovku a jednoduše přesune na nové místo. Tak je to doslova opětovné buňku. Tak být jisti, že váš názor na zakázku stůl lze nastavit pro všechny nové hodnoty, které potřebuje mimo intialization.

Odpovězeno 20/02/2009 v 22:11
zdroj uživatelem

hlasů
4

Není hrdí na toto řešení, ale funguje to s maximálním počtem možných vazeb IB:

Interface (AlbumTableViewCell je podtřídou UITableViewCell jehož instance je definována v XIb souboru AlbumViewController je):

@interface AlbumsViewController : UITableViewController {
    IBOutlet AlbumTableViewCell *tableViewCellTrack;
}

@property (nonatomic, retain) AlbumTableViewCell *tableViewCellTrack;

Implementace (Vyjmout z archivu / Archiv vytvoří kopii / klony tabulka pohled buňka):

@implementation AlbumsViewController

@synthesize tableViewCellTrack;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    AlbumTableViewCell *cell = (AlbumTableViewCell *)[tableView dequeueReusableCellWithIdentifier: @"AlbumCell"];

    if (cell == nil) {
        AlbumsViewController *albumsViewController = [[[AlbumsViewController alloc] init] autorelease];
        [[NSBundle mainBundle] loadNibNamed: @"AlbumsViewController" owner: albumsViewController options: nil];

        cell = albumsViewController.tableViewCellTrack;
    }

    cell.labelTitle.text = ...;
    cell.labelArtist.text = ...;

    return cell;
}
Odpovězeno 08/12/2009 v 10:06
zdroj uživatelem

hlasů
3

No, nejsem si jistý, proč všechny návody na to, že nestanovuje tento krok.

Při použití si vlastní UITableViewCell z hrot, volat dequeueReusableCellWithIdentifier nestačí. Musíte zadat „identifikátor“ v IB, jen pro něj v tabulkového zobrazení kartě Cell části.

Pak ujistěte se, že identifikátor dáte do IB je stejný jako identifikátor, který používáte pro dequeueReusableCellWithIdentifier.

Odpovězeno 17/06/2009 v 05:10
zdroj uživatelem

hlasů
1

Tady to je v Swift

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell : UITableViewCell?
    let cellId = String(format: "Cell%d", indexPath.row)
    cell = alertTable!.dequeueReusableCellWithIdentifier(cellId) as! UITableViewCell?

    if cell == nil {
        let archivedData = NSKeyedArchiver.archivedDataWithRootObject(masterTableCell!)
        cell = NSKeyedUnarchiver.unarchiveObjectWithData(archivedData) as! UITableViewCell?
    }

    // do some stuff

    return cell!
}
Odpovězeno 24/10/2015 v 02:00
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more