Tab Bar Item hidden behind tableview / not being shown? - swift

I have an empty view with a tab bar pictured below, when i load a routine a table appears containing the contents, however it seems to overlay the tab bar killing off app navigation. Its not sized in the storyboard to overlay it and its constraint locked to not do so, so im unsure why this is happening, pics of the issue and VC's code below:
VC Code:
import Foundation
import UIKit
import CoreData
class RoutineController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// MARK: - DECLARATIONS
#IBAction func unwindToRoutine(segue: UIStoryboardSegue) {}
#IBOutlet weak var daysRoutineTable: UITableView!
#IBOutlet weak var columnHeaderBanner: UIView!
#IBOutlet weak var todaysRoutineNavBar: UINavigationBar!
#IBOutlet weak var addTOdaysRoutineLabel: UILabel!
let date = Date()
let dateFormatter = DateFormatter()
let segueEditUserExerciseViewController = "editExerciseInRoutineSegue"
//This is the selected routine passed from the previous VC
var selectedroutine : UserRoutine?
// MARK: - VIEWDIDLOAD
override func viewDidLoad() {
super.viewDidLoad()
setupView()
daysRoutineTable.delegate = self
daysRoutineTable.dataSource = self
view.backgroundColor = (UIColor.customBackgroundGraphite())
dateFormatter.dateStyle = .short
dateFormatter.dateFormat = "dd/MM/yyyy"
let dateStr = dateFormatter.string(from: date)
todaysRoutineNavBar.topItem?.title = dateStr + " Routine"
}
// MARK: - VIEWDIDAPPEAR
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.daysRoutineTable.reloadData()
self.updateView()
}
// MARK: - TABLE UPDATE COMPONENTS
private func setupView() {
updateView()
}
// MARK: - TABLE SETUP
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let count = self.selectedroutine?.userexercises?.count
{
print("exercises: \(count)")
return count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? TodaysRoutineTableViewCell else {
fatalError("Unexpected Index Path")
}
cell.backgroundColor = UIColor.customBackgroundGraphite()
cell.textLabel?.textColor = UIColor.white
configure(cell, at: indexPath)
return cell
}
// MARK: - VIEW CONTROLER ELEMENTS VISIBILITY CONTROL
fileprivate func updateView() {
var hasUserExercises = false
if let UserExercise = self.selectedroutine?.userexercises {
hasUserExercises = UserExercise.count > 0
}
addTOdaysRoutineLabel.isHidden = hasUserExercises
columnHeaderBanner.isHidden = !hasUserExercises
daysRoutineTable.isHidden = !hasUserExercises
}
// MARK: - SETTING DATA FOR A TABLE CELL
func configure(_ cell: TodaysRoutineTableViewCell, at indexPath: IndexPath) {
if let userExercise = selectedroutine?.userexercises?.allObjects[indexPath.row]
{
print("\((userExercise as! UserExercise).name)")
cell.todaysExerciseNameLabel.text = (userExercise as! UserExercise).name
cell.todaysExerciseRepsLabel.text = String((userExercise as! UserExercise).reps)
cell.todaysExerciseSetsLabel.text = String((userExercise as! UserExercise).sets)
cell.todaysExerciseWeightLabel.text = String((userExercise as! UserExercise).weight)
}
}
}
requested table constraints
Debug hierarchy
The Segue that sends the user back to the view that looses its tab bar
if segue.identifier == "addToTodaySegue" {
let indexPath = workoutTemplateTable.indexPathForSelectedRow
let selectedRow = indexPath?.row
print("selected row\(selectedRow)")
if let selectedRoutine = self.fetchedResultsController.fetchedObjects?[selectedRow!]
{
if let todaysRoutineController = segue.destination as? RoutineController {
todaysRoutineController.selectedroutine = selectedRoutine
}
}
}
I also feel perhaps the viewDidAppear code may cause the issue, perhaps the super class?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.daysRoutineTable.reloadData()
self.updateView()
Updated storyboard image

I suspect you need to embed your viewController in a UINavigationController.
Consider the following setup:
I suspect your setup is like the upper one:
TapBar -> ViewController -show segue-> ViewController
Which results in a hidden tapbar, like in your description:
While the bottom setup:
TapBar -> NavigationCntroller -rootView-> ViewController -show segue-> ViewController
results in:
which is what you want, how I understood.
Update
It's hard to see. The screenshot of your Storyboard is in pretty low resulution, but the segues look wrong. Double check them. A Segue of type show (e.g push) looks like this:
Also clear project and derived data. Segue type changes sometime are ignored until doing so.

Try calling this self.view.bringSubviewToFront(YourTabControl).

The previous suggestion should work. But the content at the bottom part of tableview will not be visible as the tabbar comes over it. So set the bottom constraint of tableview as the height of tabbar.

Related

Table Content disappears on Scroll in TableView with Custom Cell using Subview - Swift

I have a ViewController which uses multiple Subviews (HomeViewController, etc.) which can be selected via a Custom Tab Bar at the bottom of my app. Inside the HomeViewController there is a UIView containing a UITableView containing a Prototype Custom Cell with name and image.
import UIKit
class HomeViewController: UIViewController {
#IBOutlet weak var friendView: UITableView!
let friends = ["batman", "harsh", "ava", "sasha", "fatima", "alfred"]
override func viewDidLoad() {
super.viewDidLoad()
friendView.delegate = self
friendView.dataSource = self
friendView.allowsSelection = false
}
}
extension HomeViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return friends.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = friendView.dequeueReusableCell(withIdentifier: "customCell") as! CustomCell
let friend = friends[indexPath.row]
cell.avatarImg.image = UIImage(named: friend)
cell.nameLbl.text = friend
return cell
}
}
Custom cell:
import UIKit
class CustomCell: UITableViewCell {
#IBOutlet weak var friendView: UIView!
#IBOutlet weak var nameLbl: UILabel!
#IBOutlet weak var avatarImg: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
When I start the app, everything looks just fine. However, when I start scrolling inside the table, all data suddenly disappears. All relations between storyboard and code should be just fine. I think it might have got something to do with my need of using a Subview.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var tabBarView: UIView!
#IBOutlet weak var contentView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
Design.makeCornersRound(view: tabBarView, radius: 10.0)
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: false) { (timer) in
self.switchToHomeViewController()
}
}
#IBAction func onClickTabBar(_ sender: UIButton) {
let tag = sender.tag
if tag == 1 {
switchToIncomingsViewController()
}
else if tag == 2 {
switchToSpendingsViewController()
}
else if tag == 3 {
switchToHomeViewController()
}
else if tag == 4 {
switchToSavingsViewController()
}
else if tag == 5 {
switchToSettingsViewController()
}
}
func switchToHomeViewController() {
guard let Home = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as? HomeViewController else { return }
contentView.addSubview(Home.view)
Home.didMove(toParent: self)
}
...
}
Reference to the tutorial I have been trying to implement: https://www.youtube.com/watch?v=ON3Z0PXSoVk
In this function:
func switchToHomeViewController() {
// 1
guard let Home = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as? HomeViewController else { return }
// 2
contentView.addSubview(Home.view)
// 3
Home.didMove(toParent: self)
// 4
}
At 1 you create an instance of HomeViewController
at 2 you add its view to cotentView
at 3 you call didMove() ... but that doesn't do anything because you haven't added the controller to your hierarchy
at 4 your Home instance goes away, so the code in that controller no longer exists
You need to add the controller as a child controller.
As a side note, use lowerCase for variable names:
func switchToHomeViewController() {
// create an instance of HomeViewController
guard let homeVC = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as? HomeViewController else { return }
// add it as a child view controller
self.addChild(homeVC)
// add its view
contentView.addSubview(homeVC.view)
// here you should either set the view's frame or add constraints
// such as:
homeVC.view.frame = contentView.bounds
// inform the controller that it moved to a parent controller
homeVC.didMove(toParent: self)
}

Beginner question on passing data between view controllers

I am trying to recreate the Notes app in iOS. I have created an initial View Controller which is just a table view. A user can go to a Detail View Controller to compose a new note with a Title and Body section. When they click Done, I want to manipulate the tableView with note's details.
I am struggling saving the details of what the user entered to use on my initial view controller.
Here's my Notes class which defines the notes data:
class Notes: Codable {
var titleText: String?
var bodyText: String?
}
Here is the Detail View controller where a user can input Note details:
class DetailViewController: UIViewController {
#IBOutlet var noteTitle: UITextField!
#IBOutlet var noteBody: UITextView!
var noteDetails: Notes?
var noteArray = [Notes]()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(updateNote))
noteTitle.borderStyle = .none
}
#objc func updateNote() {
noteDetails?.titleText = noteTitle.text
noteDetails?.bodyText = noteBody.text
noteArray.append(noteDetails!) // This is nil
// not sure if this is the right way to send the details over
// let vc = ViewController()
// vc.noteArray.append(noteDetails!)
if let vc = storyboard?.instantiateViewController(identifier: "Main") {
navigationController?.pushViewController(vc, animated: true)
}
}
}
I also have an array on my initial view controller as well. I think I need this one to store note data to display in the tableView (and maybe don't need the one on my Detail View controller?). The tableView is obviously not completely implemented yet.
class ViewController: UITableViewController {
var noteArray = [Notes]()
override func viewDidLoad() {
super.viewDidLoad()
print(noteArray)
self.navigationItem.setHidesBackButton(true, animated: true)
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(composeNote))
}
#objc func composeNote() {
if let dvc = storyboard?.instantiateViewController(identifier: "Detail") as? DetailViewController {
navigationController?.pushViewController(dvc, animated: true)
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
noteArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
return cell
}
Just using Delegate:
First create delegate protocol with a func to send back note to your viewController
protocol DetailViewControllerDelegate: AnyObject {
func newNoteDidAdded(_ newNote: Note)
}
Next add the delegate variable to DetailViewController, and call func noteDataDidUpdate to send data back to viewController
class DetailViewController: UIViewController {
weak var delegate: DetailViewControllerDelegate?
#objc func updateNote() {
....
delegate?.newNoteDidAdded(newNote)
}
}
finally, set delegate variable to viewController and implement this in ViewController
class ViewController: UIViewController {
....
#objc func composeNote() {
if let dvc = storyboard?.instantiateViewController(identifier: "Detail") as? DetailViewController {
dvc.delegate = self
navigationController?.pushViewController(dvc, animated: true)
}
}
}
extension ViewController: DetailViewControllerDelegate {
func newNoteDidAdded(_ newNote: Note) {
// do some thing with your new note
}
}

Swift UITableView cellForRowAt indexPath doesn't get called on tableView.reloadData() after view appeared for second time

The summary of my problem is; when the tableView.reloadData() is called upon firestore's local changes on the first time the view loads up it works and updates as it supposed to. However, after I switch forth and back with other viewControllers, although initially on viewDidAppear() tableView get's reloaded, upon local changes it no longer does so.
I've included a simpler version of my project to better explain and to make it reproducable;
Class Item
let db = Firestore.firestore()
static var list = [String:[String:Any]]()
static var listenerSet = Bool()
static var listener: ListenerRegistration!
func setListener(completion: #escaping (String) -> Void) {
if !Item.listenerSet {
print("Attaching item document listener.")
Item.listener = db.collection("Items").document("default").addSnapshotListener({ (document, error) in
let source = document!.metadata.hasPendingWrites ? "Local" : "Server"
print("Updating item data from the \(source).")
Item.listenerSet = true
Item.list = document?.get("List") as! [String:[String:Any]]
completion("Item data is set")
})
} else {
completion("Item listener already exists")
}
}
func add(itemID:String) {
let itemRef = db.collection("Items").document("default")
itemRef.setData([
"List": [
itemID : [
"Count": FieldValue.increment(1.0),
]]
], merge:true)
}
FirstViewController:UIViewController
let item = Item()
var itemList = [[String:Any]]()
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var switchBar: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
// Setting the table views
tableView.delegate = self
tableView.dataSource = self
}
override func viewDidAppear(_ animated: Bool) {
print("View Did appear") // prints OK
item.setListener() { (result) in
print(result)
loadData()
}
}
func loadData() {
itemList.removeAll()
var counter = 0
for (id,data) in Item.list {
itemList.append(data)
itemList[counter]["ID"] = id
counter += 1
}
tableView.reloadData()
}
#IBAction func switchBarChanged(_ sender: UISegmentedControl) {
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
switch switchBar.selectedSegmentIndex {
case 1:
let vc = storyBoard.instantiateViewController(identifier: "secondViewController")
show(vc, sender: self)
default:
break
}
}
Extension FirstViewController: UITableViewDataSource,UITableViewDelegate
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("These are items:\(itemList)")
print(itemList.count)
print(tableView.bounds.height)
return itemList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell") as! ItemCell
let itemID = itemList[indexPath.row]["ID"] as! String
let itemName = itemList[indexPath.row]["Name"] as! String
let itemCount = itemList[indexPath.row]["Count"] as! Double
cell.itemID = itemID
cell.itemName.text = itemName
cell.itemCount.text = String(itemCount)
print("Items within the tableView \(itemList)") // prints only in the first run whenever there is an upload, or when refreshed.
return cell
}
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let add = UIContextualAction(style: .normal, title: "Add", handler: { (action, view, completionHandler) in
item.add(itemID:(itemList[indexPath.row]["ID"] as! String))
completionHandler(true)
})
add.image = UIImage(systemName: "plus")
let configuration = UISwipeActionsConfiguration(actions: [add])
configuration.performsFirstActionWithFullSwipe = true
return configuration
}
Class ItemCell:UITableViewCell
var itemID = String()
#IBOutlet weak var itemName: UILabel!
#IBOutlet weak var itemCount: UILabel!
SecondViewController:UIViewController
#IBOutlet weak var switchBar: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func switchBarChanged(_ sender: UISegmentedControl) {
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
switch switchBar.selectedSegmentIndex {
case 0:
let vc = storyBoard.instantiateViewController(identifier: "firstViewController")
show(vc, sender: self)
default:
break
}
}
Now this is the flow I'm having issue on;
Application loads, FirstViewController loads, viewDidAppear kicks in. tableView loads.
When swiped right, the value in firestore server increments by one, snapshot listener kicks in, tableview reloads and everything works as it supposed to be.
After I switch to SecondViewController and come back to FirstViewController, viewDidAppear kicks in tableView loads.
This time however, when I swipe right again, the value in firestore server still increments by one and the snapshot listener kicks in, updating the Item.list. static var ItemList gets updated, and tableView does reload, however this time, only numberOfRowsInSection method works as it prints the count and updated itemList, then nothing happens cellForRowAt doesn't work and rows don't get updated.
Now at this stage if I go SecondViewController and comeback to FirstViewController the rows are updated, but when swiped right still no avail.
What am I missing here ? Thanks all for your replies.

Trouble with segue/unsegue when making a list app

I'm new to coding, so please bear with me. I was following an online tutorial that worked with plists to make a habit list app. I have a table view controller that shows a list of habits and a segue that presents modally a view controller that has text fields to add a habit.
enter image description here
Every time it runs, nothing happens when I click on the "save" and "cancel" buttons. I realize this is a vague question as it doesn't pinpoint to a specific issue, but I am really struggling with fixing this issue and would really appreciate if someone proofreads the code. The app builds and runs with no warnings.
This is the table view controller that shows the habits:
class TableViewController: UITableViewController {
//MARK: Properties
var habits = [Habit]()
//MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return habits.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Table view cells are reused and should be dequeued using a cell identifier.
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") else {
fatalError("The dequeued cell is not an instance of ViewController.")
}
// Fetches the appropriate habit for the data source layout.
let habit = habits[indexPath.row]
cell.textLabel?.text = habit.mainGoal
cell.detailTextLabel?.text = habit.microGoal
return cell
}
#IBAction func unwindToHabitList(sender: UIStoryboardSegue) {
if let source = sender.source as?ViewController, let habit = source.habit {
//add a new habit
let newIndexPath = IndexPath(row: habits.count, section: 0)
habits.append(habit)
tableView.insertRows(at: [newIndexPath], with: .automatic)
}
}
This is the view controller that adds a habit:
class ViewController: UIViewController, UITextFieldDelegate, UINavigationControllerDelegate {
#IBOutlet weak var saveButton: UIBarButtonItem!
#IBOutlet weak var mainGoalTextField: UITextField!
#IBOutlet weak var microGoalTextField: UITextField!
var habit: Habit?
//method for configuring controller before presenting
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
//configure this destination view controller only when save button is pressed
guard let button = sender as? UIBarButtonItem, button === saveButton else {
os_log("save button was not pressed, cancelling", log: OSLog.default, type: .debug)
return
}
let mainGoal = mainGoalTextField.text ?? ""
let microGoal = microGoalTextField.text ?? ""
//set the habit to be passed on to tableViewController after the unwind segue
habit = Habit(mainGoal: mainGoal, microGoal: microGoal)
}
#IBAction func cancel(_ sender: UIBarButtonItem) {
// Depending on style of presentation (modal or push presentation), this view controller needs to be dismissed in two different ways.
let isPresentingInAddHabitMode = presentingViewController is UINavigationController
if isPresentingInAddHabitMode {
dismiss(animated: true, completion: nil)
}
else if let owningNavigationController = navigationController{
owningNavigationController.popViewController(animated: true)
}
else {
fatalError("The ViewController is not inside a navigation controller.")
}
}
I appreciate any and all help in advance!
STORYBOARD CONNECTIONS:
TABLEVIEW CONTROLLER CONNECTIONS
ADD HABIT VIEW CONTROLLER CONNECTIONS

UIView is always behind UITableView

I have a UIViewController (not a UITableViewController because I read that a view controller is best for this kind of behaviour) with a UITableView. In this view controller I want to add a floating UIView and place it above my tableview, to do so I wrote:
public override func viewDidLoad() {
super.viewDidLoad()
// add button
let fbv = liquidActionButtonInstance.addActionButton() // this is a UIView
self.view.addSubview(fbv)
liquidActionButtonInstance.delegate = self
// delegate
tableView.delegate = self
tableView.dataSource = self
}
However my floating view appears behind my UITableView, how can I add it as the first child of self.view? I've used
self.view.addSubview(fbv)
self.view.bringSubviewToFront(fbv)
Among others and none seems to work.
Edit:
I added some screenshots of my view's hierarchy.
Edit 2:
Here I put a little more code:
My ViewController without some unrelated code:
public class ActividadesTableViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var descripcionFiltrosLabel: UILabel!
#IBOutlet weak var filtrosLabelBottomConstraint: NSLayoutConstraint!
#IBOutlet weak var filtrosLabelTopConstraint: NSLayoutConstraint!
#IBOutlet weak var tableViewTopConstraint: NSLayoutConstraint!
private var liquidActionButtonInstance: FloatingActionButton = FloatingActionButton()
public var viewModel : ActividadesTableViewModeling?
public override func viewDidLoad() {
super.viewDidLoad()
// Agregar action button
self.view.insertSubview(liquidActionButtonInstance.addActionButton(),aboveSubview: tableView)
liquidActionButtonInstance.delegate = self
// set row's height
tableView.estimatedRowHeight = 70
tableView.rowHeight = UITableViewAutomaticDimension
// delegate
tableView.delegate = self
tableView.dataSource = self
// load tableview data
if let viewModel = viewModel {
viewModel.loadActividades(withFilters: nil)
}
}
}
// MARK: FloatingButton
extension ActividadesTableViewController: FloatingActionButtonDelegate {
public func performSegueFromFloatingActionButton(segueName name: String) {
performSegueWithIdentifier(name, sender: self)
}
}
// MARK: TableView
extension ActividadesTableViewController: UITableViewDataSource, UITableViewDelegate {
public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Omitting this code, just mentioning the methods
}
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ActividadCell", forIndexPath: indexPath) as! ActividadTableViewCell
if let viewModel = viewModel {
cell.viewModel = viewModel.cellModels.value[indexPath.row]
} else {
cell.viewModel = nil
}
return cell
}
public func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
}
And this is how I add the button (in a different class):
func addActionButton() -> LiquidFloatingActionButton {
let createButton: (CGRect, LiquidFloatingActionButtonAnimateStyle) -> LiquidFloatingActionButton = { (frame, style) in
let floatingActionButton = LiquidFloatingActionButton(frame: frame)
floatingActionButton.animateStyle = style
floatingActionButton.dataSource = self
floatingActionButton.delegate = self
floatingActionButton.color = ColoresKairos.principal2
return floatingActionButton
}
let cellFactory: (String) -> LiquidFloatingCell = { (iconName) in
return LiquidFloatingCell(icon: UIImage(named: iconName)!)
}
cells.append(cellFactory("iphone-action-button-group"))
cells.append(cellFactory("iphone-action-button-notepad"))
cells.append(cellFactory("iphone-action-button-check-box"))
let floatingFrame = CGRect(x: UIScreen.mainScreen().bounds.width - 56 - 16, y: UIScreen.mainScreen().bounds.height - 56 - 16, width: 56, height: 56)
let bottomRightButton = createButton(floatingFrame, .Up)
//view.addSubview(bottomRightButton)
//return view
return bottomRightButton
}
You need to add the view using addSubview(_:) AND bringToFront(_:). You can also try sending the tableView to the back using sendToBack(_:)
In your document outline menu in your storyboard, you can place your floating view below your TableView in view hierarchy. Then, you can always see your floating view placed above your tableview.
It's gonna be like this.
▼ Your ViewController
Top Layout Guide
Bottom Layout Guide
▼View
▶︎ TableView
▶︎ Floating View
Below is the code that is working along with its screenshot, I suspect that your call liquidActionButtonInstance.addActionButton() returns an empty button?
class ViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
private var liquidButton: LiquidFloatingActionButton?
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
// Setting up the liquid button
liquidButton = createLiquidButton()
view.addSubview(liquidButton!)
}
func createLiquidButton() -> LiquidFloatingActionButton {
let frame = CGRect(x: UIScreen.mainScreen().bounds.width - 56 - 16, y: UIScreen.mainScreen().bounds.height - 56 - 16, width: 56, height: 56)
let button = LiquidFloatingActionButton(frame: frame)
button.animateStyle = .Up
button.color = UIColor.redColor()
return button
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
// UITableView Implementation, not included not relevent for the example.
}
The error here, after debugging the view hierarchy was that my tableView wasn't being added directly to the UIViewController's hierarchy, so it was added above everything else, and adding my FloatingButton as a subview of UIViewController always resulted on it being hidden by my tableView.
My tableView is added via storyboard, and as far as I know this is not the expected behaviour, but in my case just adding the following lines:
self.view.addSubview(tableView)
self.view.addSubview(liquidActionButtonInstance.addActionButton())
Solved my problem.