kopiering UITableViewCell

stemmer
7

Jeg leser en egendefinert tabellcelle i tableView:cellForRowAtIndexPath:fra en spiss fil. Dette fungerer bra for mitt formål, bortsett fra det er ganske treg.

Nå, jeg vet den riktige tingen å gjøre på lang sikt er å skape cellen helt i koden og bruke en enkelt visning, og så videre. Men dette er en prototype, og jeg ønsker ikke å legge så mye arbeid i det.

For nå, vil jeg være glad hvis jeg leste blyet bare én gang i UIViewControllerunderklassen, så tableView:cellForRowAtIndexPath:laget kopier av den. Min antakelse er at kopiering ville være raskere enn å lese blyet.

Her er hva jeg bruker til å laste blyet, som jeg kaller fra viewDidLoad:(og retainetter)

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

Alt er bra så langt. Men spørsmålet er: Hvordan kan jeg kopiere denne over og over det? Er det enda mulig?

Jeg prøvde [_cachedObject copy]og [_cachedObject mutableCopy]men UITableViewCellstøtter ikke heller kopi protokollen.

Hvis jeg må, kan jeg bare fortelle dem å ignorere hastigheten før jeg er forberedt på å fjerne blyet helt, men jeg vil heller få det går litt fortere hvis det er en lavthengende frukt her.

Noen ideer?

Publisert på 20/02/2009 klokken 20:43
kilden bruker
På andre språk...                            


5 svar

stemmer
8

Jeg tror mestring av tabellceller kan brukes sammen med dequeuing mekanisme, som gjør det mulig å lage celle en tid (fra pennesplitt eller programmatisk eller å få det lastes automatisk fra andre spiss og kobling som et utløp i IB), og deretter klone det eller dequeue det når det trengs.

UITableViewCell ikke samsvarer med NSCopying protokoll, men det støtter tastet arkivering / unarchiving mekanisme, slik at den kan brukes for kloning.

"Basert på svar ? Hvordan duplisere en UIButton i Objective C " min datakilde delegat metoden ser slik ut:

- (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;
}

Og i mitt tilfelle self.tableViewCell er en celle som ble lastet en gang fra visningen sin spiss-fil.

Jeg har ikke testet hva som vil være raskere: "arkiv + dearkivere" for å klone eller "last spiss fil + dearkivere" som rammer vil gjøre i tilfelle -loadNibNamed: Eier: alternativer: , jeg brukte denne metoden bare med praktiske hensyn, men gode sjanser for at minnet drift vs fil i drift vil være raskere.

EDIT: Det ser ikke så lett som det virket i starten. Som UIImage ikke er i samsvar med NSCoding, celler med konfigurerte UIImageViews kan ikke bare kopieres uten ekstra kode. Jepp, kopiere hele bildet er definitivt ikke en god praksis, jubel til Apple for å peke dette.

Svarte 17/03/2011 kl. 12:00
kilden bruker

stemmer
6

Bruke mobil kloning innebygd i tabellvisningen. Apple visste genererer mye tabellceller var treg. Sjekk ut dokumenter for denne metoden:

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

Du oppretter cellen en gang, da som nye celler bes bruke denne metoden for å klone eksisterende celler. Da har du bare endre hva som må endres om den nye cellen og returnere cellen objekt.

Sjekk også ut tabellvisningen realted eksempelkode levert av Apple som bruker denne metoden, og vise deg den rette veien. Det faktum mobil ble lastet fra en spiss bør ikke saken i det hele tatt.


Minor avklaring: Jeg tror ikke de ovennevnte metode klonceller for deg. I stedet tar celle objekt som har rullet ut av skjermen og bare flytter dem til et nytt sted. Så det er bokstavelig talt gjenbruk en celle. Så vær sikker på at den tilpassede tabellvisning kan settes til alle de nye verdiene den trenger utenfor intialization.

Svarte 20/02/2009 kl. 21:11
kilden bruker

stemmer
4

Ikke stolt av denne løsningen, men det fungerer med det maksimale antall mulige IB bindinger:

Interface (AlbumTableViewCell er en underklasse av UITableViewCell hvorav et eksempel er definert i AlbumViewController s XIB fil):

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

@property (nonatomic, retain) AlbumTableViewCell *tableViewCellTrack;

Gjennomføring (dearkivere / arkiv lager en kopi / kloner tabellvisningen celle):

@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;
}
Svarte 08/12/2009 kl. 09:06
kilden bruker

stemmer
3

Vel, jeg er ikke sikker på hvorfor alle tutorials der ute ikke angir dette trinnet.

Når du bruker dine egne UITableViewCell fra Nib, ringer dequeueReusableCellWithIdentifier er ikke nok. Du må angi "Identifier" i IB, bare for for det i Table View kategorien Cell delen.

Så sørg for at identifikatoren du putter i IB er den samme som identifikator du bruker for dequeueReusableCellWithIdentifier.

Svarte 17/06/2009 kl. 04:10
kilden bruker

stemmer
1

Her er det i 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!
}
Svarte 24/10/2015 kl. 02:00
kilden bruker

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