只能声明实例方法@IBAction

时间:2018-01-17 19:41:43

标签: ios swift xcode

我在Xcode上相当新,并且编码一般,所以请在这里忍受我大声笑。我正在开发我的第一个科学博览会项目应用程序,该项目基于标签,有两个主页。一页包含几个开关;无论哪个开关打开,确定另一个页面上的大按钮播放的声音或动画。

在查看了几个教程并创建我的故事板后,我开始编写将操作连接到按钮的部分到交换机。我在pushButton函数的行中继续收到以下错误:Only instance methods can be declared @IBAction

我已经检查了我的括号和括号,我不相信有错误,但由于我是初学者,我可能会遗漏一些东西。我的代码粘贴在下面,任何帮助表示赞赏。一旦我弄清楚了这个问题,空开关功能就像第一个一样。 :)

import UIKit
import AVFoundation
import AVKit

class FirstViewController: UIViewController {
    var audioPlayer = AVAudioPlayer()
    var CatSound = URL(fileURLWithPath: Bundle.main.path(forResource:    "CatSound", ofType: "mp3")!)

    //Mark: Properties
    @IBOutlet var pushButton: UIButton!

    @IBAction func meowSwitch(_ sender: UISwitch) {
        while (sender.isOn == true) {
            @IBAction func pushButton(_ sender: UIButton) {
                let CatSound = URL(fileURLWithPath: Bundle.main.path(forResource:  "CatSound", ofType: "mp3")!)
                do {
                    audioPlayer = try AVAudioPlayer(contentsOf: CatSound)
                    audioPlayer.prepareToPlay()
                } catch {
                    print("Problem in getting File")
                }
                audioPlayer.play()
            }
        }

    }

    @IBAction func barkSwitch(_ sender: UISwitch) {
    }

    @IBAction func carSwitch(_ sender: UISwitch) {
    }

    @IBAction func trainSwitch(_ sender: UISwitch) {
    }

    @IBAction func helloSwitch(_ sender: UISwitch) {
    }

    @IBAction func applauseSwitch(_ sender: UISwitch) {
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

4 个答案:

答案 0 :(得分:0)

这两个功能不能在彼此内部

 @IBAction func meowSwitch(_ sender: UISwitch) {
while (sender.isOn == true) {
    @IBAction func pushButton(_ sender: UIButton) {
        let CatSound = URL(fileURLWithPath: Bundle.main.path(forResource:  "CatSound", ofType: "mp3")!)
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: CatSound)
            audioPlayer.prepareToPlay()
        } catch {
            print("Problem in getting File")
        }
        audioPlayer.play()
    }
}

}

像这样分开

  @IBAction func pushButton(_ sender: UIButton) {
    let CatSound = URL(fileURLWithPath: Bundle.main.path(forResource:  "CatSound", ofType: "mp3")!)
    do {
        audioPlayer = try AVAudioPlayer(contentsOf: CatSound)
        /// set repeats here if you want
        audioPlayer.numberOfLoops = -1
        audioPlayer.prepareToPlay()
    } catch {
        print("Problem in getting File")
    }
    audioPlayer.play()

////

 @IBAction func meowSwitch(_ sender: UISwitch) {

       if(sender.isOn) {      
          self.pushButton(self.pushBtn)    
       }

  }

答案 1 :(得分:0)

问题在于:

@IBAction func meowSwitch(_ sender: UISwitch) {
    while (sender.isOn == true) {
        @IBAction func pushButton(_ sender: UIButton) {
            .....
        }
    }
}

你不能在另一个函数中声明一个函数。

您应该创建一个单独的函数func playMeowSound(){...},其代码位于pushButton(_ sender: UIButton)之内,然后执行:

@IBAction func meowSwitch(_ sender: UISwitch) {
    while (sender.isOn == true) {
        playMeowSound()
    }
}

答案 2 :(得分:0)

我希望这就是你想要的:

import UIKit
import AVFoundation
import AVKit

class FirstViewController: UIViewController {
    var audioPlayer = AVAudioPlayer()
    var CatSound = URL(fileURLWithPath: Bundle.main.path(forResource:    "CatSound", ofType: "mp3")!)

    //Mark: Properties

    @IBAction func pushButton(_ sender: UIButton) {
        if UserDefaults.standard.playMeowSound {
            playMeow()
        } // else if UserDefaults.standard.playBarkSound { etc.
    }

    func playMeow() {
        let CatSound = URL(fileURLWithPath: Bundle.main.path(forResource:  "CatSound", ofType: "mp3")!)
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: CatSound)
            audioPlayer.prepareToPlay()
        } catch {
            print("Problem in getting File")
        }
        audioPlayer.play()
    }
}

class SecondViewController: UIViewController {


    @IBAction func meowSwitch(_ sender: UISwitch) {
        UserDefaults.standard.playMeowSound = sender.isOn
        if sender.isOn == true {
            // turn off all the other switches, e.g.:
            // barkSwitch.isOn = false
            // UserDefaults.standard.playBarkSound = false
        }
    }
}

extension UserDefaults {
    private static let playMeowSoundKey = "org.stackoverflow.playMeowSoundKey"

    var playMeowSound: Bool {
        get {
            return UserDefaults.standard.bool(forKey: UserDefaults.playMeowSoundKey)
        }
        set {
            UserDefaults.standard.set(newValue, forKey: UserDefaults.playMeowSoundKey)
        }
    }
}

pushButton是一个@IBAction链接到按钮。按下时,此处理程序会测试哪个开关已设置,并播放您需要的声音。您希望@IBOutlet用于交换机,以便您可以测试其状态以找出哪个开关。

答案 3 :(得分:0)

每当你将一个函数放在另一个函数中时,内部函数属于外部函数,而不是类的实例。

您设置代码pushButton的方式属于meowSwitch方法,而不属于FirstViewController类,因此您不能使用@IBAction关键字。< / p>

根据您描述项目的方式,您应该考虑使用不同的界面。鉴于您希望用户在按下按钮时选择要播放的“声音或动画”,UIPickerView具有所有可能性可能会更适合您。

使用开关意味着用户可以立即全部打开,当用户按下按钮时会发生什么?

鉴于您希望在两个视图控制器上拆分,每个视图控制器都在自己的选项卡中,我会让第一个选项卡处理选择器,第二个选项卡具有触发所选项目的按钮。

在第一个视图控制器中,您将使用func pickerView(_ : ,didSelectRow: , inComponent: )将用户的选择存储在用户默认值中。

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if let chosen = self.pickerView(pickerView, titleForRow: row, forComponent: component) {
        UserDefaults.standard.set(chosen, forKey: "selected")
    }
}

请注意,要使UIPickerView正常工作需要更多设置,但有很多教程可以解释它。

然后第二个视图控制器会在按下按钮时读取默认值,并相应地做出响应。

如果所有选项都是音频文件,并且它们的名称与您在选择器视图中显示的名称相匹配,则可以使用存储在用户默认值中的字符串来播放正确的音频。

@IBAction func pushButton(_ sender: UIButton) {
    guard let selected = UserDefaults.standard.string(forKey: "selected") else { return }
    let sound = URL(fileURLWithPath: Bundle.main.path(forResource:  selected, ofType: "mp3")!)
    do {
        audioPlayer = try AVAudioPlayer(contentsOf: sound)
        audioPlayer.prepareToPlay()
    } catch {
        print("Problem in getting File")
    }
    audioPlayer.play()
}