2011-09-24 18 views
25

Potrzebuję umieścić UIView (dla reklam) na UITableView w mojej aplikacji iphone. Problem polega na tym, że kiedy przewijam tabelę na dół, dodany interfejs UIView przewija się przy stole. To, czego chcę, to to, żeby został naprawiony na dole ekranu. Czy jest jakiś sposób na zrobienie tego?iOS: Umieść UIView na UITableView w ustalonej pozycji

Jest to kod, który użyłem dodać UIView do stołu:

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

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

+0

myślę wszystkie poniższe odpowiedzi są zdezorientowane. To, co robisz, to dodanie widoku do podglądu widoku tabeli. Proste. – Jonny

Odpowiedz

26

Doceniam to stare pytanie. Ale znalazłem odpowiedzi albo z fałszywymi informacjami w części i niejasnymi fragmentami. Tak więc to, co wciąż warte jest, oto, jak dodałem widok "pływający" na dole mojego widoku UITableViewController. Tak, możesz to zrobić, nawet jeśli zaakceptowane odpowiedzi mówią, że nie możesz.

W swojej metodzie -viewDidLoad można utworzyć widok, który nazwiemy bottomFloatingView. Jest to również ustawione jako właściwość.

Pamiętaj, aby dodać zawartość do dolnej części widoku tabeli, aby uniknąć ukrywania zawartości tabeli w widoku swobodnym.

Następnie należy użyć UIScrollViewDelegate, aby zaktualizować ramkę widoku pływającego.

Iluzja będzie taka, że ​​widok utknie na dole. W rzeczywistości ten widok porusza się cały czas, przewijając i zawsze jest obliczany, aby pojawiać się na dole. Widoki przewijania są bardzo potężne! I prawdopodobnie jedna z najbardziej niedocenianych klas UIKit, jak sądzę.

Oto mój kod. Zanotuj właściwość, zawartość w widoku tabeli i implementację metody delegatów metody -scrollViewDidScroll:. Stworzyłem mój pływający widok w moim scenopisie, dlatego nie widzisz, że jest on ustawiony.

Pamiętaj także, że prawdopodobnie powinieneś używać KVO do obserwowania zmian w ramce widoku tabeli. Jest możliwe, że to się zmieni z biegiem czasu, najprostszym sposobem na sprawdzenie jest to, przełączając i wyłączając pasek stanu połączenia w symulatorze.

Ostatnia rzecz, jeśli używasz widoków nagłówka sekcji w widoku tabeli, te widoki będą najwyższym widokiem w widoku tabeli, więc możesz również przenieść widok pływający z przodu, zrób to, gdy zmieniasz jego ramkę.

@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

imponujący efekt! – Fattie

+0

niesamowite, wystarczy wziąć pod uwagę kontekst KVO, więcej informacji: [link] (http://stackoverflow.com/questions/11916502/importance-of-context-parameter-in-key-value-observing) –

+0

Dzięki za połączenie! – Daniel

10
  1. Dodaj swój pogląd na SuperView widoku tabeli (jeśli to możliwe; UITableViewController sprawia, że ​​to niemożliwe).

  2. Dodaj widok do widoku tabeli i zmień jego położenie w metodzie delegata -scrollViewDidScroll: (UITableViewDelegate to pod-protokół z UIScrollViewDelegate).

+0

Próbowałem tego - (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; } ale to w ogóle nie działa –

+2

nie używaj self.view.bounds! dopasuj tylko wartość origin.y do self.tableView.contentOffset.y –

+0

lub dodaj ją do swoich obliczeń powyżej, jeśli chcesz zachować ją wyśrodkowaną (ale nadal użyj self.tableview.bounds.size.height do centralnego obliczenia) –

32

Oto jak dla mnie zadziałało. Reklama pozostaje u dołu widoku.

W viewDidLoad w 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]; 

Następnie dodać tej metody gdzieś w tym samym pliku .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; 
} 

Nie zapomnij zadeklarować awView.

+2

Powinien to być po prostu newFrame.origin.y = aScrollView.contentOffset.y –

4

Miałem podobny problem, gdy chciałem dodać wskaźnik ładowania na moim UITableViewController. Aby rozwiązać ten problem, dodałem moje UIView jako wyeksponowanie okna. To rozwiązało problem. Tak to zrobiłem.

-(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]; 
} 
Powiązane problemy