web-dev-qa-db-ja.com

iOS:UITableViewの上に固定位置でUIViewを配置します

IPhoneアプリのUITableViewの上に(広告用の)UIViewを配置する必要があります。問題は、テーブルを一番下までスクロールすると、追加されたUIViewがテーブルとともにスクロールすることです。画面下に固定して欲しいです。それを行う方法はありますか?

これは、UIViewをテーブルに追加するために使用したコードです。

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

これは古い質問です。しかし、私は部分的に誤った情報と不明確なスニペットのどちらかで答えを見つけました。それでもまだ価値があるので、ここにUITableViewControllerのビューの下部に「フローティング」ビューを追加した方法を示します。ええ、受け入れられた答えがあなたができないと言っていても、あなたはそれを行うことができます。

-viewDidLoadメソッドで、bottomFloatingViewという名前のビューを作成できます。これもプロパティとして設定されます。

テーブルビューの下部にコンテンツインセットを追加してください。これにより、フローティングビューでテーブルのコンテンツが非表示になるのを回避できます。

次に、UIScrollViewDelegateを使用して、フローティングビューのフレームを更新する必要があります。

錯覚は、あなたの見解が下にくっついていることです。実際には、このビューはスクロールしている間常に移動しており、常に下部に表示されるように計算されています。スクロールビューは非常に強力です。そしておそらく私が思う最も過小評価されているUIKitクラスの1つです。

これが私のコードです。プロパティ、テーブルビューのコンテンツインセット、および-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
29
Daniel

これが私にとってどのように機能したかです。広告はビューの下部にとどまります。

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を宣言することを忘れないでください。

33
Adriano Lucas
  1. テーブルビューのスーパービューにビューを追加します(可能な場合はUITableViewControllerで不可能になります)。

  2. ビューをテーブルビューに追加し、-scrollViewDidScroll:delegateメソッドで再配置します(UITableViewDelegateUIScrollViewDelegateのサブプロトコルです)。

10
Martin Ullrich

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]; 
}
4
- (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];
}
0
stack Stevn