Swift:使用 StoryBoard 在 Tableview 上浮动加号按钮

Posted

技术标签:

【中文标题】Swift:使用 StoryBoard 在 Tableview 上浮动加号按钮【英文标题】:Swift: Floating Plus button over Tableview using The StoryBoard 【发布时间】:2015-07-30 13:46:19 【问题描述】:

如何使用情节提要添加浮动按钮作为 Facebook 的应用房间?

我无法在 tableview 上拖动 UIView,这是我知道的唯一方法。

【问题讨论】:

老问题,但这里有一个很棒的 Swift 库 - github.com/yoavlt/LiquidFloatingActionButton 【参考方案1】:

此按钮代码如下:

添加阴影 使按钮变圆 添加动画以引起注意

Swift 4.2:完整的视图控制器实现

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)
        
    

【讨论】:

这很好用,除了删除 viewWillDisappear 中的按钮。无法将按钮设置为 nil,并且没有调用 removeFromSuperview()。删除了 DispatchQueue 并将按钮设置为 nil。按预期工作。 嘿@MatthewBradshaw 你能告诉我你的例子吗,我有这个代码在前 50 名付费应用程序中运行,它的问题为零。如果我能对你有所帮助,我不介意帮助你:) 当然。我不能展示所有的源代码,但我可以给你一些截图等。我一定会很感激的。 答案已更新,实现完整。 @JoshuaHart 感谢您更新代码!我相信viewWillDisappear(_:) 你的意思是使用super.viewWillDisappear(animated) 而不是super.viewWillAppear(animated)?此外,对于脉冲动画,我需要将代码放入 DispatchQueue.main.async ... 以使脉冲为我工作。再次感谢!【参考方案2】:

有点晚了,但可能对某人有帮助。您可以通过编程非常轻松地做到这一点。只需创建按钮的实例,设置按钮的所需属性它最好use constraints over frame 因为它会在每个屏幕尺寸的相同位置呈现按钮。我正在发布使按钮变圆的代码。使用约束的值来改变按钮的位置和大小。

斯威夫特 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**/


【讨论】:

【参考方案3】:

在视图控制器中放置一个表格视图。然后您应该能够在表格视图顶部添加按钮。

【讨论】:

在桌子的背面如何制作在前面 否则它将在表格行内 它我自动拖动一个按钮它会在行中! 将它拖到场景中并确保它是有序的,这样按钮就在表格视图下方(但不在里面) @user3662992 你能试试上面吗【参考方案4】:

按照@Kunal Kumar 的回答,它适用于UIScrollViewUIView,但不适用于UITableView。我发现很容易让它与UITableView一起工作,只需要添加一行代码。非常感谢@Kunal Kumar

viewDidLoad 中,将self.view.addSubview(roundButton) 更改为 self.navigationController?.view.addSubview(roundButton) 它会起作用的!!

顺便说一句,我想我们需要在viewWillLayoutSubviews()方法中添加super.viewWillLayoutSubviews()

下面是上面提到的所有代码,

斯威夫特 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)])

【讨论】:

【参考方案5】:

这仅仅是因为你的 UIButton 在 UITableView 下,将它移动到情节提要的树中,所以它看起来像这样:

| View
|-- Table View
|-- Button

【讨论】:

以上是关于Swift:使用 StoryBoard 在 Tableview 上浮动加号按钮的主要内容,如果未能解决你的问题,请参考以下文章

swift - storyboard(故事版)的使用

如何在 Swift 上使用带有 Storyboard 的 UITabBarController 内的导航控制器

使用 Storyboard 的 Swift 动态表格视图单元格高度

如何使用 didSelectRowAtIndexPath(在 Swift 中)在两个 Storyboard 之间传递日期?

在 Storyboard 和 Swift 2 中禁用 UIButton 突出显示

使用 swift iOS 刷新 Storyboard 视图控制器