2011-09-24 1 views
25

Ho bisogno di mettere un UIView (per gli annunci) su UITableView nella mia app per iPhone. Il problema è che quando faccio scorrere la tabella verso il basso, l'UIView aggiunto sta scorrendo con la tabella. Quello che voglio è che sia fissato nella parte inferiore dello schermo. C'è un modo per farlo?iOS: Colloca UIView sopra UITableView in posizione fissa

Questo è il codice che ho usato per aggiungere l'UIView alla tabella:

awView = [AdWhirlView requestAdWhirlViewWithDelegate:self]; 
awView.autoresizingMask=UIViewAutoresizingFlexibleLeftMargin; 
[self.tableView addSubview:awView]; 
+0

note ... http://stackoverflow.com/questions/8258216/position-a-uiview-relative-to-the-bottom-of-the-parent-view/20287309#20287309 – Fattie

+0

penso tutte le risposte di seguito sono confuse. Quello che fai è aggiungere la tua vista alla superview della vista tabella. Semplice come quella. – Jonny

risposta

26

Apprezzo che questa è una vecchia domanda. Ma ho trovato le risposte sia con informazioni false in frammenti in parte che non chiari. Quindi per quello che vale ancora, ecco come ho aggiunto una vista "mobile" alla parte inferiore della vista del mio UITableViewController. Sì, puoi farlo anche se le risposte accettate dicono che non puoi.

Nel metodo -viewDidLoad, è possibile creare una vista che chiameremo bottomFloatingView. Anche questo è impostato come una proprietà.

Assicurati di aggiungere un riquadro di contenuto nella parte inferiore della visualizzazione tabella, questo eviterà di nascondere qualsiasi contenuto della tabella con la visualizzazione mobile.

Successivamente, è necessario utilizzare UIScrollViewDelegate per aggiornare il frame della vista mobile.

L'illusione è che la tua vista è incollata sul fondo. In realtà, questa vista si sta spostando tutto il tempo in cui si sta scorrendo e viene sempre calcolata per apparire in basso. Le visualizzazioni di scorrimento sono molto potenti! E probabilmente sono una delle classi UIKit più sottovalutate che penso.

Quindi ecco il mio codice. Annotare la proprietà, il contenuto inserito nella visualizzazione tabella e l'implementazione del metodo delegato -scrollViewDidScroll:. Ho creato la mia vista mobile nel mio storyboard, motivo per cui non riesci a vederlo configurato.

Inoltre, non dimenticare che probabilmente dovresti usare anche KVO per osservare le modifiche alla cornice della tabella. È possibile che questo cambi nel corso del tempo, il modo più semplice per verificare è quello di attivare e disattivare la barra di stato in chiamata nel simulatore.

L'ultima cosa, se stai usando le viste di intestazione di sezione nella tua vista tabella, quelle viste saranno la vista più in alto nella vista tabella, quindi dovrai anche portare la vista mobile in primo piano, fallo quando cambi la sua cornice.

@interface MyTableViewController() 
@property (strong, nonatomic) IBOutlet UIView *bottomFloatingView; 
@end 

@implementation MyTableViewController 

static NSString *const cellIdentifier = @"MyTableViewCell"; 

- (void)dealloc 
{ 
    [self.tableView removeObserver:self forKeyPath:@"frame"]; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [self.tableView addSubview:self.bottomFloatingView]; 

    self.tableView.contentInset = UIEdgeInsetsMake(0.0, 0.0, CGRectGetHeight(self.bottomFloatingView.bounds), 0.0); 
    self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0.0, 0.0, CGRectGetHeight(self.bottomFloatingView.bounds), 0.0); 

    [self.tableView addObserver:self 
        forKeyPath:@"frame" 
         options:0 
         context:NULL]; 
} 

#pragma mark - UITableViewDataSource 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return 20; 
} 

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

    cell.textLabel.text = [NSString stringWithFormat:@"Row %d", indexPath.row]; 

    return cell; 
} 

#pragma mark - UIScrollViewDelegate 

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    [self adjustFloatingViewFrame]; 
} 

#pragma mark - KVO 

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context { 
    if([keyPath isEqualToString:@"frame"]) { 
     [self adjustFloatingViewFrame]; 
    } 
} 

- (void)adjustFloatingViewFrame 
{ 
    CGRect newFrame = self.bottomFloatingView.frame; 

    newFrame.origin.x = 0; 
    newFrame.origin.y = self.tableView.contentOffset.y + CGRectGetHeight(self.tableView.bounds) - CGRectGetHeight(self.bottomFloatingView.bounds); 

    self.bottomFloatingView.frame = newFrame; 
    [self.tableView bringSubviewToFront:self.bottomFloatingView]; 
} 

@end 
+1

impressionante impressionante! – Fattie

+0

impressionante, basta prendere in considerazione il contesto di KVO, maggiori informazioni: [collegamento] (http://stackoverflow.com/questions/11916502/importanza-di-contesto-parametro-in-key-valore-osservando) –

+0

Grazie per il link! – Daniel

10
  1. Aggiungi immagine per la superview della vista tabella (se possibile; UITableViewController rende questo impossibile).

  2. Aggiungi immagine per la visualizzazione della tabella e riposizionarlo nel metodo -scrollViewDidScroll: delegato (UITableViewDelegate è un sub-protocollo di UIScrollViewDelegate).

+0

ho provato questo - (void) scrollViewDidScroll: (UIScrollView *) scrollView { \t CGSize adSize = [awView actualAdSize]; \t CGRect newFrame = awView.frame; \t \t newFrame.origin.x = (self.view.bounds.size.width - adSize.width)/2; \t newFrame.origin.y = (self.view.bounds.size.height - adSize.height/2) -21; \t awView.frame = newFrame; } ma non funziona affatto –

+2

non utilizzare self.view.bounds! regola solo il valore origin.y-valore in self.tableView.contentOffset.y –

+0

o aggiungilo al tuo calcolo sopra se vuoi mantenerlo centrato (ma usa ancora self.tableview.bounds.size.height per il calcolo del centro) –

32

Ecco come ha funzionato per me. L'annuncio rimane nella parte inferiore della visualizzazione.

In viewDidLoad, in YourController.m:

awView = [AdWhirlView requestAdWhirlViewWithDelegate:self]; 
awView.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height-kAdWhirlViewHeight/2); 
[self.view addSubview:awView]; 

Quindi aggiungere questo metodo da qualche parte nello stesso file .m:

-(void)scrollViewDidScroll:(UIScrollView *)scrollView { 
    CGRect newFrame = awView.frame; 
    newFrame.origin.x = 0; 
    newFrame.origin.y = self.tableView.contentOffset.y+(self.tableView.frame.size.height-kAdWhirlViewHeight); 
    awView.frame = newFrame; 
} 

Non dimenticare di dichiarare awView.

+2

Dovrebbe essere solo newFrame.origin.y = aScrollView.contentOffset.y –

4

Ho avuto un problema simile in cui volevo aggiungere un indicatore di caricamento sopra il mio UITableViewController. Per risolvere questo, ho aggiunto il mio UIView come sottomenu della finestra. Questo ha risolto il problema. Questo è come l'ho fatto.

-(void)viewDidLoad{ 
[super viewDidLoad]; 
//get the app delegate 
XYAppDelegate *delegate = [[UIApplication sharedApplication] delegate]; 

//define the position of the rect based on the screen bounds 
CGRect loadingViewRect = CGRectMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2, 50, 50); 
//create the custom view. The custom view is a property of the VIewController 
self.loadingView = [[XYLoadingView alloc] initWithFrame:loadingViewRect]; 
//use the delegate's window object to add the custom view on top of the view controller 
[delegate.window addSubview: loadingView]; 
}