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

时间:2016-08-06 18:02:05

标签: ios swift uiviewcontroller uibarbuttonitem uistoryboardsegue

我有一个UIViewControllerUIBarButtonItem配置为调用名为func settingsTapped(sender: AnyObject?)的自定义函数,我在其中放置了performSegueWithIdentifier。我已经确定这个函数没有被调用,即使按钮正常工作并且segue仍然可以工作,因为它会进入正确的视图控制器。

第一个VC:

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)
  }
}

在故事板中,我在导航栏中放置了一个栏按钮项目:

enter image description here

我在设置栏按钮项和设置视图控制器之间创建了一个Show(例如Push)segue,我给这个segue标识了'segueToSettings`。当我触摸设置按钮时,它会显示设置视图控制器,但它不会将我的穴居人调试行打印到控制台。

我也尝试在CalculatorViewController本身和SettingsViewController之间创建segue(我认为这可能是一种更好的方法)但是当我按照这种方式设置它时,没有任何事情发生时我触摸设置按钮。

我已经尝试了所有我能找到的东西,但没有任何效果。我希望我不会在这个问题上获得愚蠢的问题徽章。

更新1:

我还在努力解决这个问题。这是我学到的并尝试过的其他功能。单击“设置”按钮的工作原理是从按钮执行segue到我在Storyboard中创建的“设置”页面。正如人们所预料的那样,它会在执行此操作之前调用override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)。所以它完全忽略了action: #selector(settingsTapped(_:))部分。此外,我可以在故事板中更改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)
      }

与“设置”按钮类似,触摸它除了使其闪烁外什么都不做。我应该指出,我通过故事板添加了条形按钮项目,我认为这是不必要的,因为我试图以编程方式添加它们。但是,如果没有它们,则不会出现任何按钮。

1 个答案:

答案 0 :(得分:1)

经过更多的研究和更多的反复试验,我已经弄明白了。我学到了很多东西,我会留在这里给将来遇到这个问题的人。

在高级别,尝试在故事板中执行其中一些操作,而在代码中使用一些代码则很容易让人感到困惑。对我来说关键的事情是:

  1. 我没有使用开箱即用的根视图控制器与UINavigationController打交道,我正在处理UIViewController。使用UINavigationController,您不必做同样的事情。但是使用UIViewController,我必须添加UINavigationBar,我必须添加 UINavigationItem。我是通过将它们从对象库拖到我的故事板来完成的。
  2. 不要试图在UILabel中放置UINavigationBar来做我想做的事情,这让他们调用自定义函数。相信我,它不起作用,至少在我的情况下不行。
  3. 搞清楚之后我需要添加一个UINavigationItem,下一个啊哈!对我而言,我可以在其中添加多个 UIBarButtonItems这一事实(请注意:我的问题中的示例只显示一个以保持简单,但我实际上添加了三个项目)
  4. 这个谜题的神奇之处在于将我的代码连接到故事板。我只需从UINavigationItem按住Ctrl键并单击我的视图控制器,然后创建一个名为@IBOutlet weak var navItem: UINavigationItem!的@IBOutlet
  5. 我创建按钮并将其添加到视图的代码使用此插座,如此(简化):
  6. _

    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

    我在这个上烧了很多个小时。我希望这些信息可以帮助有人在将来避免这种情况。