Hvordan legger du tilpassede UITableViewCells fra XIB filer?

stemmer
279

Spørsmålet er enkelt: Hvordan du laster tilpassede trenger UITableViewCellfra XIB filer? Gjør du det kan du bruke Interface Builder til å designe dine celler. Svaret tilsynelatende er ikke enkelt på grunn av minnehåndtering problemer. Denne tråden nevner problemet og foreslår en løsning, men er forhånds NDA-frigivelse og mangler kode. Her er en lang tråd som diskuterer spørsmålet uten å gi et endelig svar.

Her er noen kode jeg har brukt:

static NSString *CellIdentifier = @MyCellIdentifier;

MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
    cell = (MyCell *)[nib objectAtIndex:0];
}

For å bruke denne koden, lage MyCell.m / .h, en ny underklasse av UITableViewCellog legge IBOutletstil komponentene du vil. Deretter oppretter du en ny Empty XIB fil. Åpne XIB filen i IB, legge til et UITableViewCellobjekt, setter sin identifikator til MyCellIdentifier, og sette sin klasse MyCell og legge til komponenter. Til slutt, koble IBOutletstil komponentene. Merk at vi ikke satt filas eier i IB.

Andre metoder argumentere sette filens eier og advarer mot minnelekkasjer hvis XIB ikke er lastet via en ekstra fabrikk klasse. Jeg testet ovenfor under instrument / Lekkasjer og så ingen minnelekkasjer.

Så hva er den kanoniske måten å laste celler fra Xibs? Har vi satt filens eier? Trenger vi en fabrikk? Hvis ja, hva er koden for fabrikken ser ut? Hvis det finnes flere løsninger, la oss klargjøre fordeler og ulemper med hver av dem ...

Publisert på 12/02/2009 klokken 07:27
kilden bruker
På andre språk...                            


23 svar

stemmer
293

Den riktige løsningen er dette:

- (void)viewDidLoad
{
 [super viewDidLoad];
 UINib *nib = [UINib nibWithNibName:@"ItemCell" bundle:nil];
 [[self tableView] registerNib:nib forCellReuseIdentifier:@"ItemCell"];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   // Create an instance of ItemCell
   PointsItemCell *cell =  [tableView dequeueReusableCellWithIdentifier:@"ItemCell"];

return cell;
}
Svarte 29/11/2012 kl. 15:57
kilden bruker

stemmer
283

Her er to metoder som de opprinnelige forfatteren statene ble anbefalt av en IB ingeniør .

Se selve innlegget for mer informasjon. Jeg foretrekker metode # 2 som det virker enklere.

Metode # 1:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
    if (cell == nil) {
        // Create a temporary UIViewController to instantiate the custom cell.
        UIViewController *temporaryController = [[UIViewController alloc] initWithNibName:@"BDCustomCell" bundle:nil];
        // Grab a pointer to the custom cell.
        cell = (BDCustomCell *)temporaryController.view;
        [[cell retain] autorelease];
        // Release the temporary UIViewController.
        [temporaryController release];
    }

    return cell;
}

Metode # 2:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
    if (cell == nil) {
        // Load the top-level objects from the custom cell XIB.
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"BDCustomCell" owner:self options:nil];
        // Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
        cell = [topLevelObjects objectAtIndex:0];
    }

    return cell;
}

Update (2014): Metode # 2 er fortsatt gyldig, men det er ingen dokumentasjon for det lenger. Det pleide å være i offisielle dokumenter , men er nå fjernet til fordel for storyboards.

Jeg postet en fungerende eksempel på Github:
https://github.com/bentford/NibTableCellExample

Svarte 21/12/2009 kl. 10:19
kilden bruker

stemmer
33

Registrere

Etter iOS 7, har denne prosessen blitt forenklet ned til ( rask 3,0 ):

// For registering nib files
tableView.register(UINib(nibName: "MyCell", bundle: Bundle.main), forCellReuseIdentifier: "cell")

// For registering classes
tableView.register(MyCellClass.self, forCellReuseIdentifier: "cell")

( Merk ) Dette er også oppnåelig ved å skape cellene i .xibeller .stroyboardfiler, som prototype celler. Hvis du trenger å legge en klasse for dem, kan du velge cellen prototype og legge tilsvarende klasse (må være en etterkommer av UITableViewCell, selvfølgelig).

dequeue

Og senere, dequeued hjelp ( swift 3.0 ):

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    cell.textLabel?.text = "Hello"

    return cell
}

Forskjellen er at denne nye metoden ikke bare dequeues cellen, skaper det også hvis ikke-eksisterende (det betyr at du ikke trenger å gjøre if (cell == nil)shenanigans), og cellen er klar til å bruke akkurat som i eksempelet ovenfor.

( Advarsel ) tableView.dequeueReusableCell(withIdentifier:for:)har den nye virkemåten, hvis du kaller den andre (uten indexPath:) får du den gamle atferden, der du må se etter nilog instans det selv, legge merke til UITableViewCell?returverdien.

if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? MyCellClass
{
    // Cell be casted properly
    cell.myCustomProperty = true
}
else
{
    // Wrong type? Wrong identifier?
}

Og selvfølgelig, type tilhørende klasse av cellen er det du som er definert i .xib filen for UITableViewCellunderklassen, eller alternativt å bruke den andre register metoden.

konfigurasjon

Ideelt sett har cellene allerede konfigurert med tanke på utseende og innhold posisjonering (for eksempel etiketter og bildevisninger) innen du registrerte dem, og på den cellForRowAtIndexPathmetoden du bare fylle dem.

Alle sammen

class MyCell : UITableViewCell
{
    // Can be either created manually, or loaded from a nib with prototypes
    @IBOutlet weak var labelSomething : UILabel? = nil
}

class MasterViewController: UITableViewController 
{
    var data = ["Hello", "World", "Kinda", "Cliche", "Though"]

    // Register
    override func viewDidLoad()
    {
        super.viewDidLoad()

        tableView.register(MyCell.self, forCellReuseIdentifier: "mycell")
        // or the nib alternative
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return data.count
    }

    // Dequeue
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "mycell", for: indexPath) as! MyCell

        cell.labelSomething?.text = data[indexPath.row]

        return cell
    }
}

Og selvfølgelig, dette er alle tilgjengelige i ObjC med samme navn.

Svarte 21/05/2015 kl. 01:47
kilden bruker

stemmer
32

Tok Shawn Craver svar og renset den opp litt.

BBCell.h:

#import <UIKit/UIKit.h>

@interface BBCell : UITableViewCell {
}

+ (BBCell *)cellFromNibNamed:(NSString *)nibName;

@end

BBCell.m:

#import "BBCell.h"

@implementation BBCell

+ (BBCell *)cellFromNibNamed:(NSString *)nibName {
    NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:NULL];
    NSEnumerator *nibEnumerator = [nibContents objectEnumerator];
    BBCell *customCell = nil;
    NSObject* nibItem = nil;
    while ((nibItem = [nibEnumerator nextObject]) != nil) {
        if ([nibItem isKindOfClass:[BBCell class]]) {
            customCell = (BBCell *)nibItem;
            break; // we have a winner
        }
    }
    return customCell;
}

@end

Jeg gjør alle mine UITableViewCell er subklasser av BBCell, og deretter erstatte standard

cell = [[[BBDetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"BBDetailCell"] autorelease];

med:

cell = (BBDetailCell *)[BBDetailCell cellFromNibNamed:@"BBDetailCell"];
Svarte 22/06/2010 kl. 02:15
kilden bruker

stemmer
15

Jeg brukte bentford sin Metode # 2 :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
    if (cell == nil) {
        // Load the top-level objects from the custom cell XIB.
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"BDCustomCell" owner:self options:nil];
        // Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
        cell = [topLevelObjects objectAtIndex:0];
    }

    return cell;
}

Det fungerer, men se opp for tilkoblinger til filens eier i den tilpassede UITableViewCell .xib fil.

Ved bestått owner:selfi din loadNibNameduttalelse, setter du UITableViewControllersom filens eier av UITableViewCell.

Hvis du drar og slipper til header filen i IB å sette opp tiltak og uttak, vil det sette dem opp som filens eier som standard.

I loadNibNamed:owner:optionsApples kode vil prøve å sette egenskaper på UITableViewController, siden det er eieren. Men du trenger ikke disse egenskapene definert der, så du får en feilmelding om å være nøkkelverdi koding-kompatibel :

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason:     '[<MyUITableViewController 0x6a383b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key myLabel.'

Dersom en hendelse blir utløst i stedet, vil du få en NSInvalidArgumentException:

-[MyUITableViewController switchValueDidChange:]: unrecognized selector sent to instance 0x8e9acd0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyUITableViewController switchValueDidChange:]: unrecognized selector sent to instance 0x8e9acd0'
*** First throw call stack:
(0x1903052 0x15eed0a 0x1904ced 0x1869f00 0x1869ce2 0x1904ec9 0x5885c2 0x58855a 0x62db76 0x62e03f 0x77fa6c 0x24e86d 0x18d7966 0x18d7407 0x183a7c0 0x1839db4 0x1839ccb 0x1f8b879 0x1f8b93e 0x585a9b 0xb904d 0x2c75)
terminate called throwing an exceptionCurrent language:  auto; currently objective-c

En enkel løsning er å peke Interface Builder tilkoblinger på UITableViewCellstedet for filens Eier:

  1. Høyreklikk på filen Eier å trekke opp listen over tilkoblinger
  2. Ta et skjermbilde med Kommando-Skift-4 (dra for å velge området som skal fanges)
  3. x koblingene fra filens eier
  4. Høyreklikk på UITableCell i objektet hierarki og legg tilkoblingene.
Svarte 19/03/2012 kl. 21:41
kilden bruker

stemmer
12

Jeg har bestemt meg for å legge ut siden jeg ikke liker noen av disse svarene - ting kan alltid bli enklere, og dette er uten tvil den mest konsise måten jeg har funnet.

1. Bygg din XIB i Interface Builder som du liker det

  • Sett filas eier til klassen NSObject
  • Legg en UITableViewCell og sette sin klasse MyTableViewCellSubclass - hvis IB krasjer (skjer i Xcode> 4 som i skrivende stund), bare bruke en UIView av gjøre grensesnittet i Xcode 4 hvis du fortsatt har det liggende
  • Layout dine subviews inni denne cellen og feste IBOutlet tilkoblinger til din @interface i .h eller BFD (BFD er min preferanse)

2. I din UIViewController eller UITableViewController underklasse

@implementation ViewController

static NSString *cellIdentifier = @"MyCellIdentier";

- (void) viewDidLoad {

    ...
    [self.tableView registerNib:[UINib nibWithNibName:@"MyTableViewCellSubclass" bundle:nil] forCellReuseIdentifier:cellIdentifier];
}

- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyTableViewCellSubclass *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    ...

    return cell;
}

3. I dine MyTableViewCellSubclass

- (id) initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        ...
    }

    return self;
}
Svarte 26/08/2013 kl. 08:18
kilden bruker

stemmer
8

Hvis du bruker Interface Builder for å lage celler, sjekk at du har satt Identifier i Inspektør. Så sjekk at det er det samme når du ringer dequeueReusableCellWithIdentifier.

Jeg tilfeldigvis glemte å sette noen identifikatorer i en tabell-tung-prosjektet, og resultatene endringen var som natt og dag.

Svarte 28/04/2010 kl. 10:55
kilden bruker

stemmer
7

Legge UITableViewCells fra XIBs sparer mye kode, men vanligvis resulterer i fryktelig rullehastigheten (faktisk, det er ikke det XIB men overdreven bruk av UIViews som forårsaker dette).

Jeg foreslår at du tar en titt på denne: Link referansen

Svarte 12/02/2009 kl. 14:19
kilden bruker

stemmer
5

Her er klassen metoden som jeg har brukt for å lage egendefinerte celler ut av XIBs:

+ (CustomCell*) createNewCustomCellFromNib {

    NSArray* nibContents = [[NSBundle mainBundle]
                            loadNibNamed:@"CustomCell" owner:self options:NULL];

    NSEnumerator *nibEnumerator = [nibContents objectEnumerator];
    CustomCell *customCell= nil;
    NSObject* nibItem = nil;

    while ( (nibItem = [nibEnumerator nextObject]) != nil) {

        if ( [nibItem isKindOfClass: [CustomCell class]]) {
            customCell = (CustomCell*) nibItem;

            if ([customCell.reuseIdentifier isEqualToString: @"CustomCell"]) {
                break; // we have a winner
            }
            else
                fuelEntryCell = nil;
        }
    }
    return customCell;
}

Så, i XIB, jeg satt klassenavnet, og gjenbruk identifikator. Etter det kan jeg bare ringe denne metoden etter mitt syn kontrolleren i stedet for

[[UITableViewCell] alloc] initWithFrame:]

Det er nok raskt nok, og blir brukt i to av mine skipsapplikasjoner. Det er mer pålitelig enn å ringe [nib objectAtIndex:0], og i mitt sinn minst, mer pålitelig enn Stephan BURLOT Rens eksempel fordi du er garantert å bare ta en visning av en XIB som er riktig type.

Svarte 12/02/2009 kl. 13:47
kilden bruker

stemmer
4

Riktig løsning er dette

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"CustomCell"];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell  *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
    return cell; 
    }
Svarte 07/09/2016 kl. 08:33
kilden bruker

stemmer
3

Sjekk dette - http://eppz.eu/blog/custom-uitableview-cell/ - veldig praktisk måte å bruke en liten klasse som ender opp en linje i kontrolleren implementering:

-(UITableViewCell*)tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath
{
    return [TCItemCell cellForTableView:tableView
                          atIndexPath:indexPath
                      withModelSource:self];
}

skriv bildebeskrivelse her

Svarte 09/07/2013 kl. 09:18
kilden bruker

stemmer
3

Omlasting NIB er dyrt. Bedre å laste det en gang, deretter instantiate objektene når du trenger en celle. Merk at du kan legge UIImageViews etc til NIB, og med flere celler, ved hjelp av denne metoden (Apples "registerNIB" iOS5 tillater kun ett toppnivå objekt - Bug 10580062 "iOS5 Tableview registerNib: altfor restriktiv"

Så min kode er under - du leser i NIB gang (i initial som jeg gjorde, eller i viewDidLoad -.. Hva Fra da av instantiate du NIB inn objektene og velge den du trenger Dette er mye mer effektivt enn å laste spiss igjen og igjen.

static UINib *cellNib;

+ (void)initialize
{
    if(self == [ImageManager class]) {
        cellNib = [UINib nibWithNibName:@"ImageManagerCell" bundle:nil];
        assert(cellNib);
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"TheCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    if(cell == nil) {
        NSArray *topLevelItems = [cellNib instantiateWithOwner:nil options:nil];
        NSUInteger idx = [topLevelItems indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop)
                            {
                                UITableViewCell *cell = (UITableViewCell *)obj;
                                return [cell isKindOfClass:[UITableViewCell class]] && [cell.reuseIdentifier isEqualToString:cellID];
                            } ];
        assert(idx != NSNotFound);
        cell = [topLevelItems objectAtIndex:idx];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"Howdie %d", indexPath.row];

    return cell;
}
Svarte 14/12/2011 kl. 19:01
kilden bruker

stemmer
2

Først importere tilpasset celle fil #import "CustomCell.h"og deretter endre representanten metoden som nedenfor nevnt:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *simpleTableIdentifier = @"CustomCell";

CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}         

     return cell;
}
Svarte 26/02/2014 kl. 06:48
kilden bruker

stemmer
2

Den riktige måten å gjøre det på er å lage en UITableViewCell underklasse implementering, header, og XIB. I XIB fjerne eventuelle visninger og bare legge en tabellcelle. Sett klassen som navnet på UITableViewCell underklasse. For filen eier, gjør det UITableViewController underklasse klassenavnet. Koble fileieren til cellen ved hjelp av tableViewCell uttaket.

I topptekstfilen:

UITableViewCell *_tableViewCell;
@property (assign) IBOutlet UITableViewCell *tableViewCell;

I gjennomføringen filen:

@synthesize tableViewCell = _tableViewCell;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *kCellIdentifier = @"reusableCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:kCellIdentifier owner:self options:nil];
        cell = _tableViewCell;
        self.tableViewCell = nil;
    }

    return cell;
}
Svarte 28/06/2012 kl. 21:57
kilden bruker

stemmer
2

Hva jeg gjør for dette er erklære en IBOutlet UITableViewCell *celli kontrolleren klassen. Deretter påkalle den NSBundle loadNibNamedklasse metoden, som vil mate den UITableViewCelltil cellen vises til ovenfor.

For xib vil jeg opprette en tom xib og legge UITableViewCellobjektet i IB hvor det kan settes opp etter behov. Dette bildet blir så koplet til den celle IBOutleti kontrolleren klassen.

- (UITableViewCell *)tableView:(UITableView *)table
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"%@ loading RTEditableCell.xib", [self description] );

    static NSString *MyIdentifier = @"editableCellIdentifier";
    cell = [table dequeueReusableCellWithIdentifier:MyIdentifier];

    if(cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"RTEditableCell"
                                      owner:self
                                    options:nil];
    }

    return cell;
}

NSBundle tillegg loadNibNamed (ADC innlogging)

cocoawithlove.com artikkelen jeg hentet ideen fra (få telefonen tall sample app)

Svarte 12/02/2009 kl. 18:01
kilden bruker

stemmer
1

I Swift 4.2 og Xcode 10

Jeg har tre XIB celle filer

i viewDidLoad registrere XIB filer som denne ...

Dette er første tilnærmingen

tableView.register(UINib.init(nibName: "XIBCell", bundle: nil), forCellReuseIdentifier: "cell1")
tableView.register(UINib.init(nibName: "XIBCell2", bundle: nil), forCellReuseIdentifier: "cell2")
//tableView.register(UINib.init(nibName: "XIBCell3", bundle: nil), forCellReuseIdentifier: "cell3")

Andre tilnærmingen direkte registrere XIB filer i cellForRowAt indexPath:

Dette er mitt tabellvisning delegat funksjoner

//MARK: - Tableview delegates
override func numberOfSections(in tableView: UITableView) -> Int {

    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return 6
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //This is first approach
    if indexPath.row == 0 {//Load first XIB cell
        let placeCell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! XIBCell
        return placeCell
    //Second approach
    } else if indexPath.row == 5 {//Load XIB cell3
        var cell = tableView.dequeueReusableCell(withIdentifier:"cell3") as? XIBCell3
        if cell == nil{
            let arrNib:Array = Bundle.main.loadNibNamed("XIBCell3",owner: self, options: nil)!
            cell = arrNib.first as? XIBCell3
        }

        //ADD action to XIB cell button
        cell?.btn.tag = indexPath.row//Add tag to button
        cell?.btn.addTarget(self, action: #selector(self.bookbtn1(_:)), for: .touchUpInside);//selector

        return cell!
    //This is first approach
    } else {//Load XIB cell2
        let placeCell = tableView.dequeueReusableCell(withIdentifier: "cell2") as! XIBCell2

        return placeCell
    }

}
Svarte 12/10/2018 kl. 07:02
kilden bruker

stemmer
1
  1. Lag din egen tilpassede klasse AbcViewCellunderklasse fra UITableViewCell(Pass på at din klasse filnavn og spiss filnavnet er det samme)

  2. Lag denne utvidelsen klassemetode.

    extension UITableViewCell {
        class func fromNib<T : UITableViewCell>() -> T {
            return Bundle.main.loadNibNamed(String(describing: T.self), owner: nil, options: nil)?[0] as! T
        }
    }
    
  3. Bruk det.

    let cell: AbcViewCell = UITableViewCell.fromNib()

Svarte 07/09/2017 kl. 04:07
kilden bruker

stemmer
0
 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

            let cellReuseIdentifier = "collabCell"
            var cell:collabCell! = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as? collabCell
            if cell == nil {
                tableView.register(UINib(nibName: "collabCell", bundle: nil), forCellReuseIdentifier: cellReuseIdentifier)
                cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! collabCell!
            }


            return cell

}
Svarte 18/05/2018 kl. 11:17
kilden bruker

stemmer
0

Her er en universell tilnærming for registrering celler i UITableView:

protocol Reusable {
    static var reuseID: String { get }
}

extension Reusable {
    static var reuseID: String {
        return String(describing: self)
    }
}

extension UITableViewCell: Reusable { }

extension UITableView {

func register<T: UITableViewCell>(cellClass: T.Type = T.self) {
    let bundle = Bundle(for: cellClass.self)
    if bundle.path(forResource: cellClass.reuseID, ofType: "nib") != nil {
        let nib = UINib(nibName: cellClass.reuseID, bundle: bundle)
        register(nib, forCellReuseIdentifier: cellClass.reuseID)
    } else {
        register(cellClass.self, forCellReuseIdentifier: cellClass.reuseID)
    }
}

Forklaring:

  1. ReusableProtokollen genererer celle-ID fra sitt klassenavn. Pass på at du følger konvensjonen: cell ID == class name == nib name.
  2. UITableViewCelli overensstemmelse med Reusableprotokollen.
  3. UITableView forlengelse sammendrag bort forskjellen i fluktende cellene ved hjelp knast eller klasse.

Bruk eksempel:

override func viewDidLoad() {
    super.viewDidLoad()
    let tableView = UITableView()
    let cellClasses: [UITableViewCell.Type] = [PostCell.self, ProfileCell.self, CommentCell.self]
    cellClasses.forEach(tableView.register)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: PostCell.self.reuseID) as? PostCell
    ...
    return cell
}
Svarte 18/08/2017 kl. 08:08
kilden bruker

stemmer
0

Denne utvidelsen krever Xcode7 beta6

extension NSBundle {
    enum LoadViewError: ErrorType {
        case ExpectedXibToExistButGotNil
        case ExpectedXibToContainJustOneButGotDifferentNumberOfObjects
        case XibReturnedWrongType
    }

    func loadView<T>(name: String) throws -> T {
        let topLevelObjects: [AnyObject]! = loadNibNamed(name, owner: self, options: nil)
        if topLevelObjects == nil {
            throw LoadViewError.ExpectedXibToExistButGotNil
        }
        if topLevelObjects.count != 1 {
            throw LoadViewError.ExpectedXibToContainJustOneButGotDifferentNumberOfObjects
        }
        let firstObject: AnyObject! = topLevelObjects.first
        guard let result = firstObject as? T else {
            throw LoadViewError.XibReturnedWrongType
        }
        return result
    }
}

Opprett en XIB fil som inneholder bare en skikk UITableViewCell.

Legger det.

let cell: BacteriaCell = try NSBundle.mainBundle().loadView("BacteriaCell")
Svarte 28/08/2015 kl. 19:44
kilden bruker

stemmer
0
 NSString *CellIdentifier = [NSString stringWithFormat:@"cell %ld %ld",(long)indexPath.row,(long)indexPath.section];


    NewsFeedCell *cell = (NewsFeedCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell=nil;

    if (cell == nil)
    {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewsFeedCell" owner:nil options:nil];

        for(id currentObject in topLevelObjects)
        {
            if([currentObject isKindOfClass:[NewsFeedCell class]])
            {
                cell = (NewsFeedCell *)currentObject;
                break;
            }
        }
}
return cell;
Svarte 11/06/2014 kl. 06:38
kilden bruker

stemmer
0

Her er min metode for at: Legge Custom UITableViewCells fra XIB filer ... enda en metode

Ideen er å skape en SampleCell underklasse av den UITableViewCellmed en IBOutlet UIView *contenteiendom og en eiendom for hver tilpasset subview du trenger å konfigurere fra koden. Deretter for å lage en SampleCell.xib fil. I denne NIB filen, endre filen eieren å SampleCell. Legg et innhold UIViewdimensjonert for å passe dine behov. Legge til og konfigurere alle subviews (label, bilde utsikt, knapper, etc) du ønsker. Til slutt, knytte innholdet utsikten og subviews i filen eier.

Svarte 24/03/2011 kl. 11:51
kilden bruker

stemmer
0

Jeg vet ikke om det er en kanonisk måte, men her er min metode:

  • Lag en xib for en ViewController
  • Sett fileieren klassen til UIViewController
  • Slett utsikten og legge til en UITableViewCell
  • Sett klasse av UITableViewCell til den tilpassede klassen
  • Sett Identifier av UITableViewCell
  • Sett utløpet av ditt syn kontrolleren utsikt til UITableViewCell

Og bruke denne koden:

MyCustomViewCell *cell = (MyCustomViewCell *)[_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
  UIViewController* c = [[UIViewController alloc] initWithNibName:CellIdentifier bundle:nil];
  cell = (MyCustomViewCell *)c.view;
  [c release];
}

I ditt eksempel, ved hjelp

[nib objectAtIndex:0]

kan bryte hvis Apple endrer rekkefølgen på elementer i xib.

Svarte 12/02/2009 kl. 09:03
kilden bruker

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