2014-08-29 9 views
9

Ho un problema con il mio UITableView in iOS7. Inizialmente, i dati vengono caricati correttamente e viene visualizzato nella mia console che dimostra che le celle stanno parlando correttamente all'origine dati, ma non appena tocco da qualsiasi parte sul tavolo, le celle scompaiono e il tavolo diventa vuoto . L'altezza delle celle nel UITableView vuoto sembra onorare l'altezza della mia cella prototipo personalizzata (410px), ma tutti i dati nelle celle svaniscono e la vista tabella vuota si comporta come se avesse solo una cella in essa (come il suo predefinito stato prima che venga collegato al delegato).Tutte le UITableCell spariscono quando si tocca UITableView in iOS 7

Sto usando Storyboard per questa app.

Per ottenere un piccolo contesto, questa app è simile all'app iphone Instagram, e sto usando questa applicazione come modo per imparare lo sviluppo di iOS 7. Ho sbattuto la testa contro un muro cercando di risolvere questo problema, e non riesco a trovare risorse online che possano aiutarmi a risolvere questo problema, quindi ho voluto chiedere a tutti gli smart peeps su Stack Overflow.

Ho preparato un grafico che ti aiuta a vedere il problema

a graphic that helps demonstrate the problem higher resolution version here

Ecco il mio codice TableViewController:

@interface PA_PhotoTableViewController() 

@property (nonatomic, copy) NSArray *photos; 

@end 



@implementation PA_PhotoTableViewController 


- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.photos = [[PA_PhotoStore sharedPhotoStore] allPhotos]; 
} 


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 1; 
} 


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return [[[PA_PhotoStore sharedPhotoStore] allPhotos] count]; 
} 


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


    PA_Photo *photo = (self.photos)[indexPath.row]; 

    cell.photoTitle.text = photo.title; 
    cell.photoOwnerName.text = [NSString stringWithFormat:@"%@", photo.owner]; 
    cell.photoLikes.text = @"99"; 

    // Photo Image URL 
    NSURL *photoImageURL = [NSURL URLWithString:photo.image_full_url]; 
    [cell.photoImage sd_setImageWithURL:photoImageURL placeholderImage:[UIImage imageNamed:@"lightGraySpinningLoader.gif"]]; 

    // Photo Owner Image 
    [cell.photoOwnerImage sd_setImageWithURL:photoImageURL placeholderImage:[UIImage imageNamed:@"lightGraySpinningLoader.gif"]]; 


    return cell; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    // This code never gets called when I try to tap on a cell 
    NSLog(@"A row was selected"); 
} 


- (void)dealloc { 
    NSLog(@"dealloc called in PA_PhotoTableViewController"); 
} 

e qui è il codice di cella personalizzato PA_PhotoCell (consolidata. h & .m file):

@interface PA_PhotoCell : UITableViewCell 

@property (nonatomic, weak) IBOutlet UIImageView *photoImage; 
@property (nonatomic, weak) IBOutlet UILabel *photoTitle; 
@property (nonatomic, weak) IBOutlet UILabel *photoOwnerName; 
@property (nonatomic, weak) IBOutlet UIImageView *photoOwnerImage; 
@property (nonatomic, weak) IBOutlet UILabel *photoLikes; 
@property (nonatomic, weak) IBOutlet UILabel *photoTimestamp; 
@property (nonatomic, weak) IBOutlet UILabel *photoComments; 

@end 



@implementation PA_PhotoCell 

- (void)setSelected:(BOOL)selected animated:(BOOL)animated { 
    [super setSelected:selected animated:animated]; 
    NSLog(@"in set selected"); 
} 


-(void)setHighlighted:(BOOL)highlighted { 
    NSLog(@"in set highlighted"); 
} 

È possibile vedere alcune chiamate NSLog() per aiutarmi a vedere se viene chiamato qualcosa.

Qualcuno può aiutarmi a vedere dove sto andando male? L'obiettivo finale è fare clic su una delle istanze di TableViewCell e lanciare un UINavigationController, so come farlo, ma non posso passare a quel passo finché non capisco perché il mio UITableView non scorre e perché scompare quando cliccaci sopra! Per favore aiuto!

Grazie in anticipo per tutti coloro che possono aiutare con questo!

EDIT: Dopo molte prove, il debug e la sperimentazione, sono stato in grado di concludere che il problema non è in realtà con l'UITableView a tutti, ed è, di fatto, un problema di come il UITableView viene caricato nella sua visualizzazione padre. Non ho ancora trovato una soluzione al mio problema, ma mi sto avvicinando alla ricerca della causa. Ecco quello che ho scoperto:

In primo luogo, quando una delle UIButtons nella parte inferiore dello schermo vengono filettati (vedi riferimento foto), carica sede competente UIViewController in un UIView chiamato placeholderView. Quando eseguo la mia problematica UITableView OUTSIDE di questo UIView (dove UITableViewController agisce da solo, non incorporato in un altro UIView), la tabella funziona perfettamente, scorre, recupera eventi di clic e così via. Quindi non appena carico UITableView in UIView, UITableView non risponde (non scorre o riceve gli eventi tap) e qualsiasi tentativo di interagire con esso, UITableView diventa completamente vuoto. La mia sessione di debug conclude che le foto NSArray * non vengono mai azzerate, o manipolate in ogni caso, la tabella diventa vuota.

Così qualcuno ha qualche idea su cosa potrebbe causare un UITableView a fare questo quando viene caricato in un UIView generico? Tutte le altre viste che vengono caricate in questo UIView generico sono reattive e si comportano come previsto. È solo questo UITableView che mi sta dando problemi.

Se rivedi il grafico che ho allegato a questo post (sopra), vedrai che sto usando quello che sembra essere un UITabBarView, ma in realtà è solo una vista generica con UIButtons all'interno. La ragione per cui ho deciso di creare il mio "UITabBarView look-alike" invece di usare la classe UITAbBarView già pronta era perché volevo dare funzionalità personalizzate al pulsante "menu" in basso a sinistra (voglio un UIView bello da far scorrere da sinistra, e fermarsi a circa 60 pixel dalla destra dello schermo quando si tocca il pulsante "menu" e non riesco a capire come personalizzare il comportamento di UITabBarView, quindi ho optato per questo approccio

Ecco il codice che viene effettivamente caricando l'UITableViewController nella visualizzazione secondaria (tramite un CustomStoryboardSegway):

// PA_HomeViewCustomStoryboardSegue.m 

#import "PA_HomeViewCustomStoryboardSegue.h" 
#import "PA_HomeViewController.h" 

@implementation PA_HomeViewCustomStoryboardSegue 

// to create a custom segue, you have to override the perform method 
-(void)perform { 

    // get the source and destination view controllers 
    PA_HomeViewController *segueSourceController = (PA_HomeViewController *)[self sourceViewController]; 
    UIViewController *destinationController = (UIViewController *)[self destinationViewController]; 

    for (UIView *view in segueSourceController.placeholderView.subviews){ 
     [view removeFromSuperview]; 
    } 

    segueSourceController.currentViewController = destinationController; 
    [segueSourceController.placeholderView addSubview:destinationController.view]; 

} 

@end 

e qui è il file di intestazione per il mio PA_HomeViewController (la vista contiene la "placeholderView" che è la vista di destinazione che carica i vari UIViewControllers dopo che l'utente ha sfruttato le UIButtons sul fondo della vista (simile ad un TabBarView):

@interface PA_HomeViewController : UIViewController 

@property (weak, nonatomic) IBOutlet UIView *placeholderView; 
@property (weak, nonatomic) UIViewController *currentViewController; 

@end 

Spero che sto solo perdendo qualcosa evidente nel modo in cui che sto caricando UITableView nel segnaposto, e qualcosa lì sta causando l'UITableView completamente vuoto.

Apprezzo molto tutti i consigli che tutti hanno offerto finora. Sono davvero ansioso di scoprire la causa di questo problema, così posso dormire la notte. haha.

+0

Hai registrato la tua cella PA_PhotoCell con la visualizzazione tabella? – Colin

+0

Questo è quello che mi stavo chiedendo, ma se non lo facesse avrebbe ottenuto un'eccezione di runtime. – Mike

+0

Un paio di domande. Sembra che l'origine dati tableview sia impostata ma agisce come se il delegato non fosse impostato. Inoltre, si comporta come dopo che una cella viene TAPpata, le foto NSArray si stanno in qualche modo rovinando. – turboc

risposta

5

Quando si visualizza UITableView in una vista diversa, è necessario assicurarsi sempre che il controller di visualizzazione che "ospita" lo UITableView abbia un forte riferimento al suo controller. Nel tuo caso, l'origine dati per UITableView sembra essere deallocata dopo aver aggiunto UITableView come sottoview.

La modifica della proprietà currentViewController da weak a strong dovrebbe risolvere il problema.

+0

Wow. Dopo giorni di sbattere la testa contro il muro ... tutto quello che dovevo fare era cambiare il riferimento da "debole" a "forte". Dopo aver seguito il tuo consiglio, le cose hanno funzionato perfettamente! Grazie! Ciò significa che dovrò davvero studiare come funziona la gestione della memoria in modo da poter evitare problemi sciocchi come questo in futuro. Apprezzo molto il vostro aiuto! –

+0

Sono contento di averlo aiutato :) In genere, tutte le proprietà del tipo di oggetto vengono contrassegnate come forti, eccetto IBOutlet, delegati e pochi altri casi speciali. – boeqqsh

+1

In swift è necessario dichiarare globalmente l'oggetto viewcontroller che risulterebbe in Strong, nel caso in cui dichiarasse localmente, il risultato è che continuano a sparire le celle. –

2

In swift è necessario dichiarare globalmente l'oggetto viewcontroller che risulterebbe in Strong, nel caso in cui dichiarasse localmente, il risultato è che le cellule scompaiono.

ad es.

var refineViewController : RefineViewController? 

allora si può accedere a tale controller utilizzando sotto il codice che non si tradurrebbe in scomparire cellule.

func showRefineView(isFindHomeTab isFindHomeTab : Bool){ 


    refineViewController = RefineViewController(nibName: String(BaseGroupedTableVC),bundle : nil) 

    refineViewController!.refineSearchDelegate = self 

    refineViewController!.view.frame = CGRectMake(0, -490, self.view.frame.size.width, self.view.frame.size.height) 

    UIView.animateWithDuration(0.3, delay: 0.0, options: .CurveEaseOut, animations: 
     { 

      self.refineViewController!.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) 
      self.refineViewController!.isFindHomeTab = isFindHomeTab 

     }, completion: nil) 

     self.view.addSubview(refineViewController!.view) 

} 
1

Ho riscontrato lo stesso identico problema. Il problema era che stavo usando una classe di origine dati personalizzata (chiamata tableVCDataSource), e stavo impostando il dataSource di tableView in modo errato nella classe ViewController. Stavo facendo:

override func viewDidLoad() { 
    mainTableView.dataSource = TableVCDataSource() 
} 

quando avrei dovuto fatto:

fileprivate var tableVCDataSource: TableVCDataSource? 

override func viewDidLoad() { 
    tableVCDataSource = TableVCDataSource() 
    mainTableView.dataSource = tableVCDataSource 
} 

Questo risolto il mio problema.

Problemi correlati