Swift: Floating Plus button over Tableview using The StoryBoard

后端 未结 5 1571
忘掉有多难
忘掉有多难 2020-12-28 08:18

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.

相关标签:
5条回答
  • 2020-12-28 08:47

    Put a table view inside a view controller. You should then be able to add the the button on top of the table view.

    0 讨论(0)
  • 2020-12-28 08:52

    This button code below:

    • Adds Shadow
    • Makes the button round
    • Adds an animation to draw attention

    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)
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-28 08:56

    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**/
    
    }
    
    0 讨论(0)
  • 2020-12-28 09:10

    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
    
    0 讨论(0)
  • 2020-12-28 09:11

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