iOS: Place UIView on top of UITableView in fixed position

后端 未结 5 2198
广开言路
广开言路 2020-12-04 13:13

I need to put a UIView (for ads) on top of a UITableView in my iphone app. The problem is that when I scroll the table to the bottom the added UIView is scrolling with the

5条回答
  •  眼角桃花
    2020-12-04 13:34

    I appreciate this is an old question. But I've found the answers either with false information in part and unclear snippets. So for what it's still worth, here is how I added a "floating" view to the bottom of my UITableViewController's view. Yes, you can do that, even if the accepted answers says you cannot.

    In your -viewDidLoad method, you can create a view which we will name bottomFloatingView. This is also set up as a property.

    Be sure to add a content inset to the bottom of your table view, this will avoid hiding any of the table's content with your floating view.

    Next, you should use the UIScrollViewDelegate to update the frame of the floating view.

    The illusion will be that your view is stuck to the bottom. In reality, this view is moving all the time you are scrolling, and is always being computed to appear at the bottom. Scroll views are very powerful ! And probably are one of the most underrated UIKit classes I think.

    So here is my code. Note the property, the content inset on the table view and the -scrollViewDidScroll: delegate method implementation. I created my floating view in my storyboard which is why you can't see that being setup.

    Also don't forget you should probably also use KVO to observe changes to the table view's frame. It's possible for that to change over time, the easiest way to test that is by toggling on and off the in call status bar in the simulator.

    Last thing, if you're using section header views in your table view, those views will be the top most view in the table view so you'll also want to bring your floating view to the front, do this when you change its frame.

    @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
    

提交回复
热议问题