Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a UIView above the current UITableViewController

I have difficulty adding a subview (UIView) from within the viewDidLoad method of a UITableViewController

This works:

[self.view addSubview:self.progView];

But you can see the table cell lines bleed through the UIView progView.

I've tried this approach:

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

Which is an attempt to add the progView, UIView to the superview, above the current view. When I try this, the UIView never appears.

-- UPDATE --

Following is the latest attempt:

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

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

Result is the same as [self.view addSubview:self.progView]; The UIView appears but seemingly behind the Table.

like image 721
user558096 Avatar asked Jan 09 '11 21:01

user558096


4 Answers

I tried the approach above, but did not get it to work. I also found it to require too much configuration and code, since it requires setting up the table view from scratch (something that is easily done from within the storyboard).

Instead, I added the view that I wanted to add above my UITableView into the UITableViewController's UINavigationController's view, as such:

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

This approach requires that you have embedded the UITableViewController in a UINavigationController, but even if you do not want a navigation controller, you can still use this approach and just hide the navigation bar.

like image 113
Daniel Saidi Avatar answered Sep 29 '22 08:09

Daniel Saidi


So 7 years have passed since my original answer, and I happen to stumble upon this problem again. Let's solve this properly once and for all:

  1. In viewDidLoad, add your subview to the (table) view.
  2. Pin the constraints relative to the safe area layout guide. This stops it from scrolling with the table contents (as pointed out in cornr's answer).
  3. In viewDidLayoutSubviews, bring the subview to the front. This ensures it doesn't get lost behind the table separators.

Swift:

override func viewDidLoad() {
    super.viewDidLoad()

    // 1.
    view.addSubview(mySubview)

    // 2. For example:
    mySubview.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        mySubview.widthAnchor.constraint(equalToConstant: 100),
        mySubview.heightAnchor.constraint(equalToConstant: 100),
        mySubview.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
        mySubview.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor)
    ])
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // 3.
    view.bringSubviewToFront(mySubview)
}

Objective-C:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 1.
    [self.view addSubview:self.mySubview];

    // 2.
    self.mySubview.translatesAutoresizingMaskIntoConstraints = false;
    [NSLayoutConstraint activateConstraints:@[
        [self.mySubview.widthAnchor constraintEqualToConstant:100],
        [self.mySubview.heightAnchor constraintEqualToConstant:100],
        [self.mySubview.centerXAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.centerXAnchor],
        [self.mySubview.centerYAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.centerYAnchor]
    ]];
}

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    // 3.
    [self.view bringSubviewToFront:self.mySubview];
}

Phew, glad that's done! Seeing how much saner this answer is, I'll omit my original answer.

Fun fact: 7 years on and I'm still an iOS developer.

like image 30
Thomas Verbeek Avatar answered Sep 29 '22 07:09

Thomas Verbeek


Ive been able to add a subview on top of a uitableviewcontroller by using uiviewcontroller containment.

UITableViewController is actually very handy when it comes to static cells and this is probably the only time where the common answer "just use uitableview" may actually not viable.

So this is how I do it.

  1. give your UITableViewController a StoryBoard identifier i.e. MyStaticTableView
  2. create a brand new UIViewController subclass and call it UITableViewControllerContainer
  3. place this controller in place of your UITableViewController inside your storyboard
  4. add a subview to the new controller and link it to an outlet called like "view_container"
  5. on you UITableViewControllerContainer viewDidLoad method

add code like:

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

Problems you may have:

  1. if you have extra top space then be sure to add the flag "wants fullscreen" to your UITableViewController
  2. if it doesn't resize properly on your UITableViewControllerContainer

add code:

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

at this point from your UITableViewController you can access you container view directly with

self.view.superview.superview

and whatever you add to it will be show on top your table view controller

like image 41
Nicola Ferruzzi Avatar answered Sep 29 '22 08:09

Nicola Ferruzzi


Swift 2018

Here is my way with storyboard:

1) Add a view in storyboard.
enter image description here

2) Link it with UITableViewController class:

@IBOutlet weak var copyrightLabel: UILabel!

3) Add it in code

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) Voilla!
enter image description here

The view will not scroll with the table view. It can be easy designable from the storyboard.

NOTE: This solution adds subview to the navigation controller and if you are going to another screen from here further down the nav, you will find this subview to persist, remove it using copyrightView.removeFromSuperView on viewDidDisappear while performing segue.

like image 44
Nik Kov Avatar answered Sep 29 '22 08:09

Nik Kov