iOS:将 UIView 放在固定位置的 UITableView 之上

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7537858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:37:13  来源:igfitidea点击:

iOS: Place UIView on top of UITableView in fixed position

iosuitableviewuiview

提问by Mohamed Emad Hegab

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 table. What I want is for it to be fixed on the bottom of the screen. Is there a way to do that?

我需要在我的 iphone 应用程序中的 UITableView 顶部放置一个 UIView(用于广告)。问题是,当我将表格滚动到底部时,添加的 UIView 与表格一起滚动。我想要的是将它固定在屏幕底部。有没有办法做到这一点?

This is the code which I have used to add the UIView to the table:

这是我用来将 UIView 添加到表的代码:

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

回答by Adriano Lucas

Here is how it worked for me. The Ad stays at the bottom of the view.

这是它对我的工作方式。广告停留在视图的底部。

In ViewDidLoad, in YourController.m:

在 ViewDidLoad 中,在 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];

Then add this method somewhere in the same .m 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;
}

Don't forget to declare awView.

不要忘记声明 awView。

回答by Daniel

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.

我很欣赏这是一个老问题。但我已经找到了部分错误信息和不清楚片段的答案。所以对于它仍然值得,这里是我如何在我的视图底部添加一个“浮动”UITableViewController视图。是的,您可以这样做,即使公认的答案说您不能。

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

在您的-viewDidLoad方法中,您可以创建一个视图,我们将其命名为 bottomFloatingView。这也设置为属性。

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 UIScrollViewDelegateto update the frame of the floating view.

接下来,您应该使用UIScrollViewDelegate来更新浮动视图的框架。

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.

错觉是你的观点被卡在了底部。实际上,此视图在您滚动时一直在移动,并且始终被计算为显示在底部。滚动视图非常强大!并且可能是我认为最被低估的 UIKit 类之一。

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.

所以这是我的代码。注意属性、表视图上的内容插入和-scrollViewDidScroll:委托方法实现。我在我的故事板中创建了我的浮动视图,这就是为什么你看不到它的设置。

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.

另外不要忘记,您可能还应该使用 KVO 来观察表格视图框架的变化。它可能会随着时间的推移而改变,最简单的测试方法是打开和关闭模拟器中的通话状态栏。

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

回答by Martin Ullrich

  1. Add your view to the superview of the table view (if possible; UITableViewControllermakes this impossible).

  2. Add your view to the table view and reposition it in the -scrollViewDidScroll:delegate method (UITableViewDelegateis a sub-protocol of UIScrollViewDelegate).

  1. 将您的视图添加到表视图的超级视图(如果可能;UITableViewController使这成为不可能)。

  2. 将您的视图添加到表视图并在-scrollViewDidScroll:委托方法中重新定位它(UITableViewDelegate是 的子协议UIScrollViewDelegate)。

回答by Salman Hasrat Khan

I had a similar problem where I wanted to add a loading indicator on top of my UITableViewController. To solve this, I added my UIView as a subview of the window. That solved the problem. This is how I did it.

我有一个类似的问题,我想在 UITableViewController 之上添加一个加载指示器。为了解决这个问题,我添加了我的 UIView 作为窗口的子视图。那解决了问题。我就是这样做的。

-(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]; 
}

回答by stack Stevn

- (void)viewDidLoad
{
    [super viewDidLoad];

    footerView = [[UIView alloc] initWithFrame:CGRectMake(0, SCREEN_HEIGHT-64, SCREEN_WIDTH, 64)];
    footerView.backgroundColor = [UIColor blueColor ];
    [self.navigationController.view addSubview:footerView];
}   

- (void)dealloc
{
    [footerView removeFromSuperview];
}