ios - 为什么我的 UIBarButtonItem 不调用我的自定义函数?

标签 ios swift uiviewcontroller uibarbuttonitem uistoryboardsegue

我有一个 UIViewController 和一个 UIBarButtonItem 配置为调用我的自定义函数 func settingsTapped(sender: AnyObject?) 我在其中'我们已经放置了 performSegueWithIdentifier。我已经确定即使按钮确实有效并且 segue 仍然有效,因为它转到了正确的 View Controller ,所以这个函数没有被调用。

第一位风投:

class CalculatorViewController: UIViewController {

  private let timeInterval = 0.016 //how frequently we change the displayed number
  private let animationLength = 0.3
  private var timer: NSTimer?
  private var counter: Int = 0
  private var max: Double = 0.0
  var startingPreferredUnits: String?
  @IBOutlet weak var weightLifted: UITextField!
  @IBOutlet weak var repetitions: UITextField!
  @IBOutlet weak var oneRepMax: UILabel!
  @IBOutlet weak var percentages: UITextView!
  @IBOutlet weak var units: UILabel! 

  override func viewDidLoad() {

    let settingsButton = UIBarButtonItem(title: "Settings", style: .Plain, target: self, action: #selector(settingsTapped(_:)))

    self.navigationItem.leftBarButtonItem = settingsButton

    super.viewDidLoad()
  }

 func settingsTapped(sender: AnyObject?) {
    startingPreferredUnits = UserDefaultsManager.sharedInstance.preferredUnits
    print("In segue, units is \(startingPreferredUnits)") // never prints this caveman debugging 
    self.performSegueWithIdentifier("segueToSettings", sender: self)
  }
}

在 Storyboard 中,我在导航栏中放置了一个 Bar Button Item:

enter image description here

我在设置栏按钮项和设置 View Controller 之间创建了一个 Show(例如 Push)转场,我已经为这个转场提供了一个标识符“segueToSettings”。当我触摸“设置”按钮时,它会显示“设置” View Controller ,但不会将我的穴居人调试行打印到控制台。

我还尝试在 CalculatorViewController 本身和 SettingsViewController 之间创建 segue(我认为这甚至可能是更好的方法)但是当我以这种方式设置它时,当我触摸“设置”按钮时什么也没有发生。

我已经尝试了我能在 SO 上找到的所有内容,但没有任何效果。我希望我不会在这个问题上获得愚蠢问题角标(Badge)。

更新 1:

我还在纠结这个问题。这是我学到并尝试过但没有用的其他东西。单击“设置”按钮通过执行从按钮到我在 Storyboard 中创建的“设置”页面的转场来工作。正如人们所预料的那样,它会在执行此操作之前调用 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)。所以它完全忽略了 action: #selector(settingsTapped(_:)) 部分。另外,我可以在 Storyboard中更改 segue 的标识符,这完全没有区别。它仍然有效。我什至可以删除标识符并且它有效。

我还尝试添加另一个按钮(这次是 barButtonSystemItem,如下所示:

 override func viewDidLoad() {
    super.viewDidLoad()

    let settingsButton = UIBarButtonItem(title: "Settings", style: .Plain, target: self, action: #selector(settingsTapped(_:)))

let saveButton = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: #selector(self.saveThisLift(_:)))

    self.navigationItem.leftBarButtonItem = settingsButton
    self.navigationItem.rightBarButtonItem = saveButton
  }  


  func saveThisLift(sender: UIBarButtonItem) {
    print("I'm in saveThisLift") // never prints
    let weight = weightLifted.text
    let reps = repetitions.text
    let maxAmount = oneRepMax.text
    let unitsText = units.description

    coreDataStack.saveLiftEvent(currentLiftName!, formula: currentFormulaName!, weight: weight!, repetitions: reps!, maxAmount: maxAmount!, unitsUsed: unitsText)
}

 func settingsTapped(sender: AnyObject?) {
        startingPreferredUnits = UserDefaultsManager.sharedInstance.preferredUnits
        print("In segue, units is \(startingPreferredUnits)") // never prints this caveman debugging 
        self.performSegueWithIdentifier("segueToSettings", sender: self)
      }

就像“设置”按钮一样,触摸它除了使其闪烁外什么也做不了。我应该指出,我通过 Storyboard添加了条形按钮项目,我认为这是不必要的,因为我试图以编程方式添加它们。但是,如果没有它们,这两个按钮都不会出现。

最佳答案

经过更多的研究和更多的试验和错误,我已经弄明白了。我学到了很多东西,我会留在这里供将来遇到此问题的任何人使用。

在高层次上,尝试在 Storyboard 中执行一些操作而在代码中执行一些操作很容易让人感到困惑。对我来说关键是:

  1. 我处理的不是 UINavigationController 及其现成的 Root View Controller ,而是 UIViewController。使用 UINavigationController,您不必做那么多。但是对于 UIViewController,我必须添加一个 UINavigationBar,并且我必须添加一个 single UINavigationItem .为此,我将它们从对象库拖到 Storyboard中。
  2. 不要试图在 UINavigationBar 中放置一个 UILabel 来执行我正在尝试执行的操作,即让它们调用自定义函数。相信我,这是行不通的,至少对我来说是行不通的。
  3. 在弄清楚我需要添加一个 UINavigationItem 之后,下一个啊哈!对我来说最重要的是我可以在其中放入多个 UIBarButtonItems(注意:我在问题中的示例只显示了一个以保持简单,但我实际上添加了三个项)
  4. 拼图的神奇之处在于将我的代码连接到 Storyboard。我只是从我的 UINavigationItem 按住 Ctrl 单击到我的 View Controller ,并创建了一个名为 @IBOutlet weak var navItem: UINavigationItem!
  5. 的 @IBOutlet
  6. 我创建按钮并将它们添加到 View 的代码像这样使用这个导出(简化):

_

class CalculatorViewController: UIViewController {

  @IBOutlet weak var navItem: UINavigationItem!

  override func viewDidLoad() {
    super.viewDidLoad()

    let settingsButton = UIBarButtonItem(title: "Settings", style: .Plain, target: self, action: #selector(self.segueToSettings(_:)))

    let viewLogButton = UIBarButtonItem(title: "Log", style: .Plain, target: self, action: #selector(self.segueToLog(_:)))

    let saveButton = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: #selector(self.saveLift(_:)))

    self.navItem.leftBarButtonItem = settingsButton
    self.navItem.rightBarButtonItems = [saveButton, viewLogButton] 
  }

func saveLift(sender: AnyObject) {
    let weight = weightLifted.text
    let reps = repetitions.text
    let maxAmount = oneRepMax.text
    let unitsText = units.text

    coreDataStack.saveLiftEvent(currentLiftName!, formula: currentFormulaName!, weight: weight!, repetitions: reps!, maxAmount: maxAmount!, unitsUsed: unitsText!)

    performSegueWithIdentifier("segueToLog", sender: self)
  }
}

最后,当你创建那个@IBOutlet 时,不要将它命名为 navigationItem: UINavigationItem 因为这会让 Xcode 非常不高兴:

enter image description here

我为此耗费了很多时间。我希望这些信息可以帮助人们在将来避免这种情况。

关于ios - 为什么我的 UIBarButtonItem 不调用我的自定义函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38807272/

相关文章:

ios - MVVM:使用闭包、无主或弱 self 将 View 与 ViewModel 绑定(bind)?

ios - 调整单元格大小以适合标签,已设置图像大小并且标签有一些圆角

ios - 在 Swift 中使用多个 ViewController 和 SKScene

objective-c - 在表格 View 单元格上长按手势

ios - 如何在进入后台后杀死 NSTimer 并在应用程序恢复事件后创建一个新计时器?

ios - NSKeyedArchiver 不保存自定义对象属性

ios - 将强引用转换为对 self 的弱引用

ios - 在 subview 中添加 UIViewController

ios - 使用 View Controller 中的方法调用模态视图,该 View 在加载之前覆盖该 View Controller 的 View

objective-c - 自定义 friendsPickerViewController 的样式