How to add a UIView above the current UITableViewController

后端 未结 20 734
旧时难觅i
旧时难觅i 2020-11-27 11:57

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

This works:

[self.view addSubview:self.prog         


        
相关标签:
20条回答
  • 2020-11-27 12:53

    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.

    0 讨论(0)
  • 2020-11-27 12:55

    Swift 4

    This is the most simplified version of a number of answers here where we are recomposing the view hierarchy. This approach does not require additional outlets for storyboards / nibs and will also work with programmatically constructed instances.

    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)
    
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题