【问题标题】:iOS: Place UIView on top of UITableView in fixed positioniOS:将 UIView 放置在 UITableView 顶部的固定位置
【发布时间】:2011-11-24 04:04:44
【问题描述】:

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

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

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

【问题讨论】:

标签: ios uitableview uiview


【解决方案1】:

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

在 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];

然后将此方法添加到同一个 .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;
}

别忘了声明 awView。

【讨论】:

  • 应该只是 newFrame.origin.y = aScrollView.contentOffset.y
【解决方案2】:

我很欣赏这是一个老问题。但是我找到了部分错误信息和不清楚的sn-ps的答案。所以对于它仍然有价值的东西,这就是我如何在UITableViewController 的视图底部添加一个“浮动”视图。是的,您可以这样做,即使接受的答案表明您不能这样做。

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

请务必在表格视图的底部添加内容插入,这样可以避免浮动视图隐藏表格的任何内容。

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

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

这是我的代码。注意属性、表格视图上的内容插入和-scrollViewDidScroll: 委托方法实现。我在情节提要中创建了浮动视图,这就是为什么您看不到正在设置的原因。

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

最后一件事,如果您在表格视图中使用部分标题视图,这些视图将是表格视图中最顶部的视图,因此您还需要将浮动视图放在前面,当您改变它的框架。

@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

【讨论】:

  • 太棒了,只考虑KVO的上下文,更多信息:link
  • 这很好,但对我来说它似乎出现在表格的底部,然后在一瞬间后猛拉。
  • 我在 Xcode 6.4 中实现此功能时遇到问题。当我滚动时它似乎可以工作,但是如果我删除一个项目或添加一个项目,它会进入列表的底部,而不是卡在视图的底部。你有机会帮我吗?我唯一无法从这段代码中实现的是 KVO,这会导致它无法正常运行吗?
【解决方案3】:
  1. 将您的视图添加到表视图的超级视图(如果可能;UITableViewController使这不可能)。

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

【讨论】:

  • 我试过这个 -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ CGSize adSize = [awView actualAdSize]; CGRect newFrame = awView.frame; newFrame.origin.x = (self.view.bounds.size.width - adSize.width)/2; newFrame.origin.y = (self.view.bounds.size.height - adSize.height/2) -21; awView.frame = newFrame; } 但它根本不起作用
  • 不要使用 self.view.bounds!仅将 origin.y 值调整为 self.tableView.contentOffset.y
  • 如果你想保持居中,也可以将其添加到上面的计算中(但仍使用 self.tableview.bounds.size.height 进行居中计算)
  • 您不需要将视图添加为超级视图。您可以将子视图添加到表格视图中,但您需要提供内容插入以避免“浮动”视图隐藏任何内容。
  • 丹尼尔在下面的回答要好得多。
【解决方案4】:

我有一个类似的问题,我想在我的 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]; 
}

【讨论】:

    【解决方案5】:

    对于像我这样寻找使用 Swift 的简单解决方案的人来说,这些答案有点过时了。这是我所做的(假设 myCustomView 是在文件的其他位置建立的):

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
       
        let pixelsFromBottom = CGFloat(20)//or whatever the
        let theHeight = self.tableView.frame.height + scrollView.contentOffset.y
        myCustomView.frame = CGRect(x: 0, y: theHeight - pixelsFromBottom , width: self.view.frame.width, height: myCustomView.frame.height)
    
    }
    

    【讨论】:

      【解决方案6】:
      - (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];
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多