I have a view controller which contains a table view. In this view controller, I've also set up a floating panel. The floating panel is not appearing for some reason, however. I know the ContentViewController is working, so I didn't include that code. The error is somewhere in this code and I can't find it. It's like the FloatingPanel is just not being added to the view.
import Foundation
import UIKit
import FloatingPanel
class Section {
let title: String
let options: [String]
var isOpened: Bool = false
init(title: String,
options: [String],
isOpened: Bool
) {
self.title = title
self.options = options
self.isOpened = isOpened
}
}
class PicsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UINavigationControllerDelegate, FloatingPanelControllerDelegate {
@IBOutlet weak var addButton: UIButton!
private let picsTableView: UITableView = {
let picsTableView = UITableView()
picsTableView.register(UITableViewCell.self,
forCellReuseIdentifier: "cell")
return picsTableView
}()
private var sections = [Section]()
let backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
/*------------START FLOATING PANEL-------------*/
var fpc: FloatingPanelController!
override func viewDidLoad() {
super.viewDidLoad()
print("PicsViewController LAUNCHED!!")
fpc = FloatingPanelController()
fpc.delegate = self
// guard let contentVC = storyboard?.instantiateViewController(identifier: "fpc_content") as? ContentViewController else {
// print("Failed to instantiate storyboard")
// return
// }
let contentVC = ContentViewController()
fpc.set(contentViewController: contentVC)
// fpc.track(scrollView: contentVC.collectionView)
fpc.addPanel(toParent: self)
/*------------END FLOATING PANEL-------------*/
// Set up models
picsTableView.delegate = self
picsTableView.dataSource = self
picsTableView.frame = view.bounds
picsTableView.backgroundColor = backgroundColor
view.addSubview(picsTableView)
sections = [
Section(title: "Section 1", options: ["Test 1", "Test 2", "Test 3"], isOpened: false),
Section(title: "Section 2", options: ["Test 1", "Test 2", "Test 3"], isOpened: false),
Section(title: "Section 3", options: ["Test 1", "Test 2", "Test 3"], isOpened: false),
Section(title: "Section 4", options: ["Test 1", "Test 2", "Test 3"], isOpened: false)
]
// get rid of extra table view cells
picsTableView.tableFooterView = UIView()
// customize button
addButton.layer.cornerRadius = 0.5 * addButton.bounds.size.width
addButton.clipsToBounds = true
addButton.backgroundColor = .red
addButton.tintColor = .white
addButton.setImage(#imageLiteral(resourceName: "plus-5-512"), for: .normal)
view.bringSubviewToFront(addButton)
}
@IBAction func addButtonTapped(_ sender: Any) {
print("Add button tapped")
}
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let section = sections[section]
if section.isOpened {
return section.options.count + 1
} else {
return 1
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = picsTableView.dequeueReusableCell(
withIdentifier: "cell",
for: indexPath
)
cell.backgroundColor = .clear
cell.textLabel?.textColor = .black
if indexPath.row == 0 {
cell.textLabel?.text = sections[indexPath.section].title
} else {
cell.textLabel?.text = sections[indexPath.section].options[indexPath.row - 1]
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
picsTableView.deselectRow(at: indexPath, animated: true)
if indexPath.row == 0 {
sections[indexPath.section].isOpened = !sections[indexPath.section].isOpened
picsTableView.reloadSections([indexPath.section], with: .none)
} else {
print("Tapped sub cell \(indexPath.row)")
}
}
}
Typically, 3 or 4 statements to add any view controller as subview to any view controllers are
let viewController = SomeViewController()
self.addChild(viewController)
self.view.addSubview(viewController.view)
viewController.didMove(toParent: self)
Because you havent provided the implementation for addPanel
where you are calling fpc.addPanel(toParent: self)
, I assume it does something similar to what I have written above, if I were to write it, I might write something like
func addPanel(toParent: UIViewController) {
toParent.addChild(self)
toParent.view.addSubview(self.view)
//add constraints or set frames for your subview
self.didMove(toParent: toParent)
}
Finally, you are adding multiple view's to your view controller's view namely a floating panel, tableView, and a button. Because you add panel before you add all other views it might be hidden under other subviews like tableView
, you can obviously check this hypothesis using view debugger, and simplest way to fix it would be to use bringSubviewToFront
, but issue is you are not holding the reference of FloatingPanelController
's view so you can try adding self.view.bringSubviewToFront(fpc.view)
as last statement of ViewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// all other codes of yours
self.view.bringSubviewToFront(fpc.view)
}
and for some reason if that doesnt work call fpc.addPanel(toParent: self)
as last statement of ViewDidLoad
instead of adding in between and add bringSubviewToFront
as last statement of addPanel(toParent
method
override func viewDidLoad() {
super.viewDidLoad()
print("PicsViewController LAUNCHED!!")
fpc = FloatingPanelController()
fpc.delegate = self
let contentVC = ContentViewController()
fpc.set(contentViewController: contentVC)
picsTableView.delegate = self
picsTableView.dataSource = self
picsTableView.frame = view.bounds
picsTableView.backgroundColor = backgroundColor
view.addSubview(picsTableView)
sections = [
Section(title: "Section 1", options: ["Test 1", "Test 2", "Test 3"], isOpened: false),
Section(title: "Section 2", options: ["Test 1", "Test 2", "Test 3"], isOpened: false),
Section(title: "Section 3", options: ["Test 1", "Test 2", "Test 3"], isOpened: false),
Section(title: "Section 4", options: ["Test 1", "Test 2", "Test 3"], isOpened: false)
]
// get rid of extra table view cells
picsTableView.tableFooterView = UIView()
// customize button
addButton.layer.cornerRadius = 0.5 * addButton.bounds.size.width
addButton.clipsToBounds = true
addButton.backgroundColor = .red
addButton.tintColor = .white
addButton.setImage(#imageLiteral(resourceName: "plus-5-512"), for: .normal)
view.bringSubviewToFront(addButton)
fpc.addPanel(toParent: self) //added as last statement
}
and
func addPanel(toParent: UIViewController) {
toParent.addChild(self)
toParent.view.addSubview(self.view)
self.didMove(toParent: toParent)
toParent.view.bringSubviewToFront(self.view)
}