如何使用 Swift 从 UITabBarController 的子类触发动作

Posted

技术标签:

【中文标题】如何使用 Swift 从 UITabBarController 的子类触发动作【英文标题】:How to trigger an action from a subclass of UITabBarController using Swift 【发布时间】:2020-03-13 03:57:39 【问题描述】:

我在我的 ios 应用程序上创建了一个 UITabBarController 的子类,因为我想在标签栏上添加一个中间的“+”按钮。我使用下面的代码添加了这个额外的按钮:

class XGTabBarViewController: UITabBarController 

let menuButton = UIButton(frame: CGRect(x: 0, y: 0, width: 70, height: 70))
private let optionMenu = UIAlertController(title: nil, message: "New", preferredStyle: .actionSheet)

override func viewDidLoad() 
    super.viewDidLoad()

    let action1 = UIAlertAction(title: "Action 1", style: .default)
    let action2 = UIAlertAction(title: "Action 2", style: .default)
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)

    optionMenu.addAction(action1)
    optionMenu.addAction(action2)
    optionMenu.addAction(cancelAction)

    var menuButtonFrame = menuButton.frame
    let iconConfig = UIImage.SymbolConfiguration(pointSize: 24, weight: .medium, scale: .medium)

    let iconImage = UIImage(systemName: "plus", withConfiguration: iconConfig)
    let icon = UIImageView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
    icon.image = iconImage
    icon.tintColor = UIColor.white

    menuButtonFrame.origin.y = view.bounds.height - menuButtonFrame.height - 50
    menuButtonFrame.origin.x = view.bounds.width/2 - menuButtonFrame.size.width/2
    menuButton.frame = menuButtonFrame

    menuButton.backgroundColor = UIColor(named: "LinkBlue")
    menuButton.layer.cornerRadius = menuButtonFrame.height/2
    menuButton.layer.shadowColor = UIColor.black.cgColor
    menuButton.layer.shadowRadius = 3
    menuButton.layer.shadowOpacity = 0.3
    menuButton.layer.shadowOffset = CGSize(width: 0, height: 3)

    menuButton.addSubview(icon)
    icon.translatesAutoresizingMaskIntoConstraints = false
    icon.widthAnchor.constraint(equalToConstant: 30).isActive = true
    icon.heightAnchor.constraint(equalToConstant: 30).isActive = true
    icon.centerXAnchor.constraint(equalTo: menuButton.centerXAnchor).isActive = true
    icon.centerYAnchor.constraint(equalTo: menuButton.centerYAnchor).isActive = true

    view.addSubview(menuButton)

    menuButton.addTarget(self, action: #selector(menuButtonAction(sender:)), for: .touchUpInside)

    view.layoutIfNeeded()


@objc private func menuButtonAction(sender: UIButton) 
    self.present(optionMenu, animated: true, completion: nil)

我通过 IB 设置标签栏控制器。这就是它的样子

那么,我想知道是否应该在此类中定义菜单按钮操作?还是有更好的(最佳实践)方法来做到这一点?

如您所见,我尝试添加一个在点击按钮时将显示的操作表。但是我遇到了一些布局错误。我想知道我是否在正确的位置添加了此代码。

我收到以下错误:

谢谢!

【问题讨论】:

你的约束被打破了......但你把代码放在了正确的地方 而不是 view.addSubview ... 做 tabBar.addSubview(button) 我这样做了,但是按钮不再显示了。 @CrisDenopol 请在我认为可行的前 -37 值中设置图像插图。 【参考方案1】:

请添加标签栏控制器和三个视图控制器连接到标签栏。 center viewcontroller tabbar itam set image inset.

没有布局错误。

import UIKit

class TabBarVC: UITabBarController 

override func viewDidLoad() 
    super.viewDidLoad()


    let tabBar = self.tabBar
    (tabBar.items![0] ).selectedImage = UIImage(named:"icn_audio_icon")?.withRenderingMode(.alwaysOriginal)
    (tabBar.items![1] ).selectedImage = UIImage(named:"icn_home_active")?.withRenderingMode(.alwaysOriginal)
    tabBar.items![2].image = UIImage(named:"icn_categary")?.withRenderingMode(.alwaysOriginal)

    tabBar.items![0].image = UIImage(named:"icn_audio_icon")?.withRenderingMode(.alwaysOriginal)
    tabBar.items![1].image = UIImage(named:"icn_home")?.withRenderingMode(.alwaysOriginal)
    tabBar.items![2].image = UIImage(named:"icn_categary")?.withRenderingMode(.alwaysOriginal)

    self.tabBarController?.selectedIndex = 1
    tabBar.layer.shadowColor = UIColor.red.cgColor
    tabBar.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
    tabBar.layer.shadowRadius = 5
    tabBar.layer.shadowOpacity = 0.6
    tabBar.layer.masksToBounds = false



  override func viewDidLayoutSubviews() 
     super.viewDidLayoutSubviews()
     self.tabBar.invalidateIntrinsicContentSize()
  



func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool 
  if viewController.isKind(of: ActionViewController.self) 
     let vc =  ActionViewController()
     vc.modalPresentationStyle = .overFullScreen
     self.present(vc, animated: true, completion: nil)
     return false
  
  return true

【讨论】:

当我点击中间按钮时如何显示操作表? 对不起,我完全迷路了。我不知道 tabBarController() 方法是干什么用的。而且 ActionViewController() 方法似乎也不合适。它没有在任何地方定义。无论如何,谢谢你的帮助。我非常感谢您的尝试【参考方案2】:

看来我的代码毕竟是正确的。但显然 UIAlertController 存在一个错误,导致它破坏布局。解决方法可在此链接中找到

Swift default AlertViewController breaking constraints

【讨论】:

以上是关于如何使用 Swift 从 UITabBarController 的子类触发动作的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 如何从 mapViewkit 中的 API 数据创建要使用的局部变量

如何使用 swift 从 iOS 设备上传文件(到 REDCap)

如何使用 Emscripten 将 Hello Word 从 Swift 编译为 JavaScript

如何使用 Swift 从 iOS HealthKit 应用程序读取心率?

如何使用 Swift 从 iOS HealthKit 应用程序读取心率?

如何使用swift从ios应用程序调用苹果钱包