How to Add floating button as Facebook\'s App Rooms using the storyboard?
I can\'t drag UIView on the tableview that\'s the only way I know.
Put a table view inside a view controller. You should then be able to add the the button on top of the table view.
This button code below:
Swift 4.2: COMPLETE VIEW CONTROLLER IMPLEMENTATION
import Foundation
public class FloatingButtonViewController: UIViewController {
private var floatingButton: UIButton?
// TODO: Replace image name with your own image:
private let floatingButtonImageName = "NAME OF YOUR IMAGE"
private static let buttonHeight: CGFloat = 75.0
private static let buttonWidth: CGFloat = 75.0
private let roundValue = FloatingButtonViewController.buttonHeight/2
private let trailingValue: CGFloat = 15.0
private let leadingValue: CGFloat = 15.0
private let shadowRadius: CGFloat = 2.0
private let shadowOpacity: Float = 0.5
private let shadowOffset = CGSize(width: 0.0, height: 5.0)
private let scaleKeyPath = "scale"
private let animationKeyPath = "transform.scale"
private let animationDuration: CFTimeInterval = 0.4
private let animateFromValue: CGFloat = 1.00
private let animateToValue: CGFloat = 1.05
public override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
createFloatingButton()
}
public override func viewWillDisappear(_ animated: Bool) {
guard floatingButton?.superview != nil else { return }
DispatchQueue.main.async {
self.floatingButton?.removeFromSuperview()
self.floatingButton = nil
}
super.viewWillDisappear(animated)
}
private func createFloatingButton() {
floatingButton = UIButton(type: .custom)
floatingButton?.translatesAutoresizingMaskIntoConstraints = false
floatingButton?.backgroundColor = .white
floatingButton?.setImage(UIImage(named: floatingButtonImageName), for: .normal)
floatingButton?.addTarget(self, action: #selector(doThisWhenButtonIsTapped(_:)), for: .touchUpInside)
constrainFloatingButtonToWindow()
makeFloatingButtonRound()
addShadowToFloatingButton()
addScaleAnimationToFloatingButton()
}
// TODO: Add some logic for when the button is tapped.
@IBAction private func doThisWhenButtonIsTapped(_ sender: Any) {
print("Button Tapped")
}
private func constrainFloatingButtonToWindow() {
DispatchQueue.main.async {
guard let keyWindow = UIApplication.shared.keyWindow,
let floatingButton = self.floatingButton else { return }
keyWindow.addSubview(floatingButton)
keyWindow.trailingAnchor.constraint(equalTo: floatingButton.trailingAnchor,
constant: self.trailingValue).isActive = true
keyWindow.bottomAnchor.constraint(equalTo: floatingButton.bottomAnchor,
constant: self.leadingValue).isActive = true
floatingButton.widthAnchor.constraint(equalToConstant:
FloatingButtonViewController.buttonWidth).isActive = true
floatingButton.heightAnchor.constraint(equalToConstant:
FloatingButtonViewController.buttonHeight).isActive = true
}
}
private func makeFloatingButtonRound() {
floatingButton?.layer.cornerRadius = roundValue
}
private func addShadowToFloatingButton() {
floatingButton?.layer.shadowColor = UIColor.black.cgColor
floatingButton?.layer.shadowOffset = shadowOffset
floatingButton?.layer.masksToBounds = false
floatingButton?.layer.shadowRadius = shadowRadius
floatingButton?.layer.shadowOpacity = shadowOpacity
}
private func addScaleAnimationToFloatingButton() {
// Add a pulsing animation to draw attention to button:
DispatchQueue.main.async {
let scaleAnimation: CABasicAnimation = CABasicAnimation(keyPath: self.animationKeyPath)
scaleAnimation.duration = self.animationDuration
scaleAnimation.repeatCount = .greatestFiniteMagnitude
scaleAnimation.autoreverses = true
scaleAnimation.fromValue = self.animateFromValue
scaleAnimation.toValue = self.animateToValue
self.floatingButton?.layer.add(scaleAnimation, forKey: self.scaleKeyPath)
}
}
}
Its a bit late, but may be it can help someone. You can do it very easily via programatically. Just create an instance of the button, set the desired property of button It is preferable to use constraints over frame
cause it'll render the button at same position on every screen size. I am posting the code which will make the button round. Play with the value of constraints to change the position and size of button.
Swift 3
var roundButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
self.roundButton = UIButton(type: .custom)
self.roundButton.setTitleColor(UIColor.orange, for: .normal)
self.roundButton.addTarget(self, action: #selector(ButtonClick(_:)), for: UIControlEvents.touchUpInside)
self.view.addSubview(roundButton)
}
override func viewWillLayoutSubviews() {
roundButton.layer.cornerRadius = roundButton.layer.frame.size.width/2
roundButton.backgroundColor = UIColor.lightGray
roundButton.clipsToBounds = true
roundButton.setImage(UIImage(named:"your-image"), for: .normal)
roundButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
roundButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -3),
roundButton.bottomAnchor.constraint
(equalTo: self.view.bottomAnchor, constant: -53),
roundButton.widthAnchor.constraint(equalToConstant: 50),
roundButton.heightAnchor.constraint(equalToConstant: 50)])
}
/** Action Handler for button **/
@IBAction func ButtonClick(_ sender: UIButton){
/** Do whatever you wanna do on button click**/
}
It's simply because your UIButton is under the UITableView, move it in the storyboard's tree so it appears like this :
| View
|-- Table View
|-- Button
Following the answer of @Kunal Kumar, it works on the UIScrollView
, and UIView
, but it doesn't works on the UITableView
. I found it is easy to make it works with UITableView
, only need to add one line code. Thank you so much @Kunal Kumar
in the viewDidLoad
, change self.view.addSubview(roundButton)
to
self.navigationController?.view.addSubview(roundButton)
and it will work!!
by the way, I think we need to add super.viewWillLayoutSubviews()
in the viewWillLayoutSubviews()
method.
below is the all code with above mentioned,
Swift 3
// MARK: Floating Button
var roundButton = UIButton()
func createFloatingButton() {
self.roundButton = UIButton(type: .custom)
self.roundButton.setTitleColor(UIColor.orange, for: .normal)
self.roundButton.addTarget(self, action: #selector(ButtonClick(_:)), for: UIControlEvents.touchUpInside)
//change view to navigationController?.view, if you have a navigationController in this tableview
self.navigationController?.view.addSubview(roundButton)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
roundButton.layer.cornerRadius = roundButton.layer.frame.size.width/2
roundButton.backgroundColor = UIColor.lightGray
roundButton.clipsToBounds = true
roundButton.setImage(UIImage(named:"ic_wb_sunny_48pt"), for: .normal)
roundButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
roundButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -3),
roundButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -53),
roundButton.widthAnchor.constraint(equalToConstant: 50),
roundButton.heightAnchor.constraint(equalToConstant: 50)])
}