web-dev-qa-db-ja.com

現在のUITableViewControllerの上にUIViewを追加する方法

UITableViewControllerのviewDidLoadメソッド内からサブビュー(UIView)を追加するのが難しい

これは動作します:

[self.view addSubview:self.progView];

ただし、UIView progViewを介して表のセル行がにじむのを確認できます。

私はこのアプローチを試しました:

[self.view.superview insertSubview:self.progView aboveSubview:self.view];

これは、現在のビューの上に、progView、UIViewをスーパービューに追加する試みです。これを試しても、UIViewは表示されません。

-更新-

以下は最新の試みです。

UIView *myProgView = (UIView *)self.progView; //progView is a method that returns a UIView

[self.tableView insertSubview:myProgView aboveSubview:self.tableView]; 
[self.tableView bringSubviewToFront:myProgView];

結果は[self.view addSubview:self.progView]と同じです。 UIViewは表示されますが、テーブルの背後に表示されます。

55
user558096

上記の方法を試しましたが、うまくいきませんでした。また、テーブルビューをゼロからセットアップする必要があるため(ストーリーボード内から簡単に実行できること)、構成とコードが多すぎることがわかりました。

代わりに、UITableViewの上に追加したいビューをUITableViewControllerのUINavigationControllerのビューに追加しました。

[self.navigationController.view addSubview:<view to add above the table view>];

この方法では、UITableViewControllerをUINavigationControllerに埋め込む必要がありますが、Navigation Controllerが必要ない場合でも、この方法を使用して、Navigation Barを非表示にすることができます。

93
Daniel Saidi

これは実際には非常に可能で簡単です-ほんの少しの再配線が必要です。同様の状況に遭遇し、これをコーディングして、テーブルビューの上部にロード画面を追加できるようにしました。このアプローチでは、静的なテーブルセルを独自のコンテンツで使用することもできます。

コントローラーがStoryboardまたはXIBのUITableViewControllerであり、既存のテーブルビューを保持しながらself.viewを標準UIViewに再割り当てする場合:

これらのインスタンス変数をヘッダーファイルに追加します。

IBOutlet UITableView *tableViewReference; // to keep a reference to the tableview
UIView *viewReference; // a reference to the new background view

ストーリーボードまたはXIBファイル:tableViewUITableViewControllertableViewReference変数に接続します。

次に、実装ファイル

// Override the default accessors of the tableview and view
- (UITableView*)tableView { return tableViewReference; }
- (UIView*)view { return viewReference; }

- (void)viewDidLoad
{
    [super viewDidLoad];

    // instantiate the new self.view, similar to the tableview
    viewReference = [[UIView alloc] initWithFrame:tableViewReference.frame];
    [viewReference setBackgroundColor:tableViewReference.backgroundColor];
    viewReference.autoresizingMask = tableViewReference.autoresizingMask;
    // add it as a subview
    [viewReference addSubview:tableViewReference];

    /* remainder of viewDidLoad */

}

奇妙に思えるかもしれませんが、UITableViewControllerは、背後で参照を使用して、風変わりなことをたくさん行っています。スワップを行うには、viewDidLoadまで待つ必要があります。このポイントの後、アクセサーは正しいUIViewUITableViewをポイントします。

使用法:次のようなもの

    [self.view addSubview:myView];

テーブルビューのコンテンツをmyViewスクロールせずに、テーブルビューの前にUIView myViewを追加します。

注:この回答は、ソリューションに境界線の逆説的なコードが含まれていることが指摘された後に編集されました。 UITableViewControllerは、保持する参照に対して奇妙なことをします。いくつかのより慎重なテストがこの単純な答えを導き出しました:)

28
Thomas Verbeek

ビューのレイヤーのzPositionを増やすことができます。

これにより、他のビュー(デフォルトで0に等しいzPositionを持つビュー)の上に表示されます。

self.progView.layer.zPosition++;
[self.view addSubview:self.progView];
11
Paco_777

Uiviewcontrollerの包含を使用して、uitableviewcontrollerの上にサブビューを追加できました。

UITableViewControllerは、静的セルに関しては実際に非常に便利です。これはおそらく、「uitableviewを使用するだけ」という一般的な答えが実際には実行できない唯一の時間です。

だからこれは私がそれを行う方法です。

  1. ITableViewController StoryBoard識別子、つまりMyStaticTableViewを指定します
  2. 真新しいIViewControllerサブクラスを作成し、それを呼び出しますITableViewControllerContainer
  3. ストーリーボード内のITableViewControllerの代わりにこのコントローラーを配置します
  4. 新しいコントローラーにサブビューを追加し、「view_container」と呼ばれるアウトレットにリンクします
  5. あなたにITableViewControllerContainer viewDidLoadメソッド

次のようなコードを追加します。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    UITableViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"MyStaticTableView"];
    [self addChildViewController:vc];
    [self.view_container addSubview:vc.view];
}

あなたが持っているかもしれない問題:

  1. 余分な上部スペースがある場合は、UITableViewControllerにフラグ「wants fullscreen」を追加してください
  2. uITableViewControllerContainerで適切にサイズ変更されない場合

コードを追加:

- (void)viewWillAppear:(BOOL)animated
{
    [[self.view_container.subviews lastObject] setFrame:self.view.frame];
}

この時点で、UITableViewControllerからコンテナビューに直接アクセスできます。

self.view.superview.superview

追加したものはすべて、Table View Controllerの上に表示されます

11
Nicola Ferruzzi

Swift 2018

これがストーリーボードの使用方法です。

1)ストーリーボードにビューを追加します。
enter image description here

2)UITableViewControllerクラスにリンクします:

@IBOutlet weak var copyrightLabel: UILabel!

3)コードに追加する

self.navigationController?.view.addSubview(copyrightView)
copyrightView.frame = CGRect(x: 0,
                            y: self.view.bounds.size.height - copyrightView.bounds.size.height,
                            width: self.view.bounds.size.width,
                            height: copyrightView.bounds.size.height)

4)出来上がり!
enter image description here

ビューはテーブルビューでスクロールしません。ストーリーボードから簡単に設計できます。

注:このソリューションは、ナビゲーションコントローラーにサブビューを追加します。ここからナビゲーションのさらに別の画面に移動する場合、このサブビューが持続することがわかります。 、セグエの実行中にviewDidDisappearでcopyrightView.removeFromSuperViewを使用して削除します。

8
Nik Kov

UITableViewControllerはUIViewControllerのサブクラスであるため、目的のビューをそのスーパービューに追加する必要があります。

Swift:
self.view.superview?.addSubview(viewTobeAdded)

Objective C:
[self.view.superview addSubview: viewTobeAdded];
7
Saikiran K

問題は、viewUITableViewControllerプロパティがtableViewプロパティと同一であることです。つまり、ルートビューはalwaysTable View Controllerであり、サブビューとして追加されるものはすべてTable View機能の対象となります。これには他の望ましくない副作用があります。たとえば、サブビューをスクロールしたくない場合にスクロールします。

ここにはいくつかのオプションがあります。 loadViewをオーバーライドして、独自のビューとテーブルビューをインストールできます。

// note: untested
- (void)loadView {
    self.view = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
    self.view.backgroundColor = [UIColor whiteColor];

    UITableView *tblView = [[UITableView alloc]
        initWithFrame:CGRectZero
        style:UITableViewStylePlain
    ];

    tblView.autoresizingMask =
        UIViewAutoresizingFlexibleWidth |
        UIViewAutoresizingFlexibleHeight
    ;

    self.tableView = tblView;
    [self.view addSubview:tblView];
    [tblView release];
}

そして、サブビューを追加する必要がある場合は、必要に応じてself.tableViewの下または上に追加します。

別のオプションは、必要なことを行うUIViewControllerサブクラスを作成することです。 UITableViewControllerはそれほど多くは追加しません。また、実装する小さな機能は簡単に複製できます。 コードの再利用を増やすためにUITableViewControllerを再作成する のような記事があり、これを簡単に行う方法を説明しています。

私は同様の問題を抱えていて、以下のコードを使用して解決しました:

     [self.navigationController.view insertSubview:<subview> 
       belowSubview:self.navigationController.navigationBar];

これにより、スタックに存在するコントローラーを使用してビューが正しい場所に挿入されます。

6

Appleの例 "iPhoneCoreDataRecipes"は、NIBを使用してヘッダーをUITableViewにロードしています。 here を参照してください:

5
Olaf

テーブルの上に画像を追加しました。私はこのコードを使用しました:

self.tableView.tableHeaderView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"header.png"]];
4
carmen_munich

iOS 11のアップデート:

AutoLayout制約を安全な領域に使用するときに、サブビューをUITableViewに追加できるようになりました。これらのビューは、TableViewに沿ってスクロールしません。

この例では、UITableViewUITableViewControllerの上にあるNavigationBarの下にビューを配置します

[self.tableView addSubview:self.topBarView];
[NSLayoutConstraint activateConstraints:@[
    [self.topBarView.topAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.topAnchor],
    [self.topBarView.leadingAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.leadingAnchor],
    [self.topBarView.trailingAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.trailingAnchor],
    [self.topBarView.heightAnchor constraintEqualToConstant:40.0]
]];
2
cornr

Swift(Daniel Saidiと同等):

コントローラーがStoryboardまたはXIBのUITableViewControllerであり、既存のテーブルビューを保持しながらself.viewを標準UIViewに再割り当てする場合:

@IBOutlet var tableViewReference: UITableView!
var viewReference: UIView!

次に、実装ファイルで:

これらのインスタンス変数をTable View Controllerファイルに追加します。

override var tableView: UITableView! {
    get { return tableViewReference }
    set { super.tableView = newValue }
}

override var view: UIView! {
    get { return viewReference }
    set { super.view = newValue }
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.edgesForExtendedLayout = UIRectEdge.None
    self.extendedLayoutIncludesOpaqueBars = false
    self.automaticallyAdjustsScrollViewInsets = false

    //rewiring views due to add tableView as subview to superview
    viewReference = UIView.init(frame: tableViewReference.frame)
    viewReference.backgroundColor = tableViewReference.backgroundColor
    viewReference.autoresizingMask = tableViewReference.autoresizingMask
    viewReference.addSubview(tableViewReference)
}

ストーリーボードまたはXIBファイルで:UITableViewControllerのtableViewをtableViewReference変数に接続します。

その後、次のように子ビューを追加できます。

self.view.addSubView(someView)
2
D. Sergeev

UITableViewControllerのテーブルビューの上にUIViewを保持するために、デリゲートメソッド(UITableViewDelegate)の1つ(または複数)を使用しています。

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.addSubview(headerView)
}

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    tableView.addSubview(overlayView) // adds view always on top
}
// if using footers in table view
tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) { ... }

ビューには、継ぎ目が良い解決策であるスーパービューが1つしかありませんので、間違っていたら修正してください。まだ60fpsを取得しているので、私には問題ありません。

1
Tomasz Kwolek

試してください:[self.view bringSubviewToFront:self.progView];

または、self.progViewをテーブルのビューに追加してみてください。

1
WrightsCS

Swift 4

これは、ビュー階層を再構成する多数の回答の中で最も単純化されたバージョンです。このアプローチでは、ストーリーボード/ペン先用の追加のアウトレットは必要なく、プログラムで構築されたインスタンスでも機能します。

class MyTableViewController: UITableViewController {

    var strongTableView: UITableView?

    override var tableView: UITableView! {
        get {
            return strongTableView ?? super.tableView
        }
        set {
            strongTableView = newValue
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // theoretically we could use self.tableView = self.tableView but compiler will not let us assign a property to itself
        self.tableView = self.view as? UITableView
        self.view = UIView(frame: self.tableView!.frame)
        self.view.addSubview(tableView)

    }

}
1
Brody Robertson

次のコードをviewDidAppearに配置するだけです。

[self.tableView.superview addSubview:<your header view>];
1
Mig70

これをしない理由があるかもしれませんが、これは今のところうまくいきます。 APを使用する場合

viewDidLayoutSubviews内でこれを実行できますが、必ず一度だけ実行するようにしてください

self.searchTableView = [[UITableView alloc] initWithFrame:self.tableView.frame style:UITableViewStylePlain];
self.searchTableView.backgroundColor = [UIColor purpleColor];
[self.view.superview addSubview:self.searchTableView];
0
Bob Spryn

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

次のようなものを試してください:

[self.tableView addSubview:overlayView];
overlayView.layer.zPosition = self.tableView.backgroundView.layer.zPosition + 1;
0
Filip Raj