简体   繁体   中英

Add button on top of UITableViewController (Swift)

I am trying to add a button ontop of a uitableview controller table view. The view controller has a navigation controller and static cells, which is why it is a uitableviewcontroller and not a uiviewcontroller. Now I am trying to add a button at the bottom of the screen that is attached to the navigation controller so that it doesn't scroll with the table view.

I am trying to make something similar to what is below. It has a navigation controller for the top bar, a table view with static cells and then a button, but how did they do the button?

Image: http://postimg.org/image/ilsmqqrip/

Thanks!

UPDATE: How can I use a uiviewcontroller with a tableview with static cells using Swift?

I find Container Views very useful in this scenario! A clean solution and very easy to implement.

Just create a normal UIViewController, add your button and a ContainerView as subviews of this UIViewController (the middle one in the image below). Finally create Embed Segue from ContainerView to your UITableViewController (the one on the right).

故事板

This way you can use static cell prototypes, not being limited only to UITableView at the same time.

Result:

结果

there is a better solution for this. you can do this by disabling the Auto Layout(button.translatesAutoresizingMaskIntoConstraints = false) property of the corresponding Button or any UIView for floating button:

Swift 4

//create a button or any UIView and add to subview
let button=UIButton.init(type: .system)
button.setTitle("NEXT", for: .normal)
button.frame.size = CGSize(width: 100, height: 50)
self.view.addSubview(button)

//set constrains
button.translatesAutoresizingMaskIntoConstraints = false
if #available(iOS 11.0, *) {
     button.rightAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.rightAnchor, constant: -10).isActive = true
     button.bottomAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
} else {
     button.rightAnchor.constraint(equalTo: tableView.layoutMarginsGuide.rightAnchor, constant: 0).isActive = true
     button.bottomAnchor.constraint(equalTo: tableView.layoutMarginsGuide.bottomAnchor, constant: -10).isActive = true
}

I did something similar with UITableViewController and a static datasource. I added the button in the footerview of my tableview.

To make it align to the bottom of the screen i needed this code in my viewcontroller:

override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        // Make footerview so it fill up size of the screen
       // The button is aligned to bottom of the footerview 
       // using autolayout constraints
        self.tableView.tableFooterView = nil
        self.footerView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.tableView.frame.size.height - self.tableView.contentSize.height - self.footerView.frame.size.height)
        self.tableView.tableFooterView = self.footerView
    }

In short, I resize the footerview to take up all the remaining space after the contentsize of the table view is removed. Since the button is aligned to the bottom of the footerView with autolayout, it will stay in the bottom of the screen.

The Storyboard:

故事板

Here is the result:

模拟器

The UITableViewController will take up the whole space, so you won't be able to add the button. Refactor your UITableViewController based code into UIViewController with UITableView manually added. This way you will be able to set the size of your table view and put the button to the bottom.

Unfortunately UITableViewController has a tableView as its top level view. Of course if you look in the view debugger you can see that the tableview is not the root view. Therefore you can add the buttons to the tableView's window programatically. If you have to do it after the fact, this is probably the easiest way to add a top level element over a UITableViewController. Otherwise if you are doing it in the initial design, you can use container view for your buttons and a UITableViewController for the TableView. The downside of this approach is you end up with two view controllers, one for the container and one for the table and its often necessary to pass information back and for between them. If you are using swift you can simplify this by nesting the tableViewcontroller inside the container view controller class.

If you want to add a button to the window, you can do this lazily once you are sure that the view has a window. Note that the buttons belong to the window and not to the view controller, so its your responsibility to remove them when the view controller disappears.

    private weak var button: UIButton!
    ...
    override func didMove(toParentViewController parent: UIViewController?) {
        super.didMove(toParentViewController: parent)
        guard self.button == nil, let window = tableView.window else {
            return
        }
        let button = UIButton(frame: CGRect(x:0, y:40, width: 200, height: 20))
        button.setTitle("This is a red button", for: .normal)
        button.backgroundColor = UIColor.red
        window.addSubview(button)
        self.button = button
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        button?.removeFromSuperview()
    }

all you need to do is to add your Top view whichever it is to the navigationController.view like so:

self.navigationController?.view.addSubview(YOUR_TOP_VIEW)

so if you need a sticky button/view etc... on top of TableViewController which does not scroll with tableView, use this approach.

Step 1 :-

Drag and drop one uiview to UITable View Controller (Static) Automatically it sticks to the bottom.

If you need to, you can also add two buttons inside UIView... It depends on your requirements.

Step 2 :-

Connect the outlet for uiview (outletView)

Step 3 :-

Add this below code in View Will Appear.

override func viewWillAppear(_ animated: Bool) {

    outletViewBottom.backgroundColor = .red
    tableView.addSubview(outletViewBottom)

    // set position
    outletView.translatesAutoresizingMaskIntoConstraints = false
    outletView.leftAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.leftAnchor).isActive = true
    outletView.rightAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.rightAnchor).isActive = true
    outletView.bottomAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.bottomAnchor).isActive = true
    outletView.widthAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.widthAnchor).isActive = true
    outletView.heightAnchor.constraint(equalToConstant: 50).isActive = true // specify the height of the view

}

Step 4 :-

Now run the code... Happy coding.

Here is a UIViewController, with a UITableView added as a subview. At the top right, you can see a dropdown that says Content: Dynamic Prototypes. Change it to Static Cells.在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM