only instance methods can be declared #IBAction building audio app - swift

I've been trying to build an IOS app that will allow me to click a button and have audio play and I'm getting stuck on this error only instance methods can be declared #IBAction. I've had a search and it doesn't seem like I've closed it out of the class or anything like that but it still doesn't want to work
import UIKit
import AVFoundation
class LevelAStartingSoundViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
#IBAction func Sbutton(_ sender: Any, forEvent event: UIEvent) {
playSound(sound: "Ssound", type: "wav")
}
}
}

If you reformat your code (Ctrl + i), you'll notice that Sbutton is inside viewDidLoad.
You need to move it outside.
#IBAction func sButton(_ sender: UIButton) { /// make sure you have the right function signature
playSound(sound: "Ssound", type: "wav")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}

Related

How to properly end a ARView that uses a Reality Composer project?

My project has a few views before it call a ARview with a reality composer project. I enabled the coaching view in it using the demo code that apple provides. My problem is. If I make a button to go back from that view and call it again, the camera starts to flick from second to second. If I do it again, the flick increases until that, if I do it again, the program crashes. How can I make that view completely new, like the first time I loaded it? I’ve tried removing the anchor from the view.session. Tried pausing the ar session. Could anyone help me with that?
This is my code
import UIKit
import RealityKit
import ARKit
class ARHomeViewController: UIViewController {
#IBOutlet var arView: ARView!
#IBOutlet weak var coachingOverlay: ARCoachingOverlayView!
override func viewDidLoad()
{
super.viewDidLoad()
presentCoachingOverlay()
addScene()
}
/// Begins the coaching process that instructs the user's movement during
/// ARKit's session initialization.
func presentCoachingOverlay() {
coachingOverlay.session = arView.session
coachingOverlay.delegate = self
coachingOverlay.goal = .horizontalPlane
coachingOverlay.activatesAutomatically = false
self.coachingOverlay.setActive(true, animated: true)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Prevent the screen from being dimmed to avoid interuppting the AR experience.
UIApplication.shared.isIdleTimerDisabled = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
arView?.session.pause()
}
func addScene()
{
guard let anchor = try? ExperienciaCasa.loadMenu() else { return }
anchor.generateCollisionShapes(recursive: true)
arView.scene.addAnchor(anchor)
}
}

SWIFT - Variable resetting when back from second ViewController

I have been searching for hours here and Google but still didn't find the answer. Everything point to passing variable from a VC to an other but not how to keep variables alive on the VC.
I can pass variables from a VC to an other using multiple methods such as singleton but when I go from second VC to the main VC I'm still facing the same problem.
Exemple you have the main VC which have a label and 2 buttons. When you click one of the button the label text change and then you click the second button to Segue to the second VC. Then when you comeback to the first VC the problem appear: the label is reseted to it's initial text "label". Why?
I tried using global variable in a separate swift file. I said to myself well the value is stored in an other swift file there is no reason why the value of the label reset.. but well it's still resetting.
Thanks so much.
Example in video: https://youtu.be/Wx5blkQqU7E
Very basic example:
varTest.swift
import Foundation
var myVar2: String!
Main ViewController
import UIKit
class ViewController: UIViewController {
#IBOutlet var mylabel: UILabel!
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.
}
#IBAction func dsfg(_ sender: UIButton) {
performSegue(withIdentifier: "switchForm", sender: self)
}
#IBAction func changeLabeltext(_ sender: UIButton) {
myVar2 = "Good."
mylabel.text = myVar2
}
}
Second ViewController
import UIKit
class ViewController2: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnPrint(_ sender: UIButton) {
performSegue(withIdentifier: "returnForm", sender: self)
}
}
I think the problem is that you are not returning back from ViewController2 to ViewController, but you are pushing a new ViewController instance, which will display a new UILabel with its default value. You can create an unwind segue from your second view controller to the first view controller, or you can call dismiss(animated:completion:) on the second view controller. This article can guide you to create an unwind segue.
When you "performSegue", the values in the ViewController class are reset - don't use segue.
Or alternatively: You mention that you tried to use global variables in a separate swift file. Use a temp file stored on the client side instead.
Use these func to create a file and write to it:
//This OVERWRITES already existing files!
func createFileinDocumentDirectory(filename: String){
let blank = ""
if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
let fileURL = dir.appendingPathComponent(filename)
do {
try blank.write(to: fileURL, atomically: false, encoding: .utf8)
}
catch let error as NSError {
print("Ooooops! Something went wrong: \(error)")
}
}
}
func writeToFileInDocumentDirectory(filename: String, textToAdd: String){
do {
let dir: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last! as URL
let url = dir.appendingPathComponent(filename)
try textToAdd.appendLineToURL(fileURL: url as URL)
}
catch {
print("Could not write to file")
}
}

After press of the button no sound plays in the iOS simulator

I'm looking for reasons why my sound won't play in the iOS simulator.
Program runs but when I press the button no sound plays.
This is my code:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var player:AVAudioPlayer?
func playSound() {
if let soundURL = Bundle.main.url(forResource: "sound", withExtension: "mp3") {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: soundURL)
if let thePlayer = player {
thePlayer.prepareToPlay()
thePlayer.play()
}
}
catch {
print(error)
}
}
}
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.
}
#IBAction func Button(_ sender: Any) {
playSound()
}
}
Do I need changes in my code or in my simulator setup?
Had a similar issue, you have to go to System Preferences > Sound > Sound Effects and then uncheck and recheck "Play user interface sound effects".
Actually found out that all I had to do was delete the file and re add it. Instead of dragging the file into Xcode I needed to add it by right clicking and adding the file that way

loadHTMLString and "thread 1 exc_bad_access (code=exc_i386_gpflt)"

Well, I'm not sure it is a real problem but it is unpleasant to see an error. The "thread 1 exc_bad_access (code=exc_i386_gpflt)" error appears with a probability of about 50% in simulator. But there is no error in real device.
I tried to use optionals, but without a noticeable result.
I have only WKWebView and a Button. The code is:
import UIKit
import WebKit
class ViewController: UIViewController {
#IBOutlet weak var WebView: WKWebView!
let all = ["kjhgjhkg","qqqqqqqqq", "wwwwwwwww", "lllllllll", "bbbbbbbb"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
WebView.loadHTMLString("<h1>The first title</h1>", baseURL: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func btnRefresh(_ sender: UIButton) {
let RandomNomber = Int(arc4random_uniform(UInt32(all.count)))
// let myString = all[RandomNomber]
// let myString2 = "<h1>" + myString + "</h1>"
WebView.loadHTMLString("<h1>" + all[RandomNomber] + "</h1>", baseURL: nil)
}
}

Remove done button in M13PDFKit swift

I'm using M13PDFKit and having a little problem. In the example the done button is not there, but when I try it shows. I don't know how to remove it. The done button looks like this. Im using Swift
in View controller just like this
import UIKit
import M13PDFKit
class ViewController: UIViewController {
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.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "NEXT" {
let viewer: PDFKBasicPDFViewer = segue.destinationViewController as! PDFKBasicPDFViewer
viewer.enableBookmarks = true
viewer.enableBookmarks = true
viewer.enableOpening = true
viewer.enablePrinting = true
viewer.enableSharing = true
viewer.enableThumbnailSlider = true
//Load the document (pdfUrl represents the path on the phone of the pdf document you wish to load)
let pdfUrl = "/Users/developer/Library/Developer/CoreSimulator/Devices/C8DC5F44-B2FC-4FC3-8E10-B87FC00791FA/data/Containers/Data/Application/047BE9AD-F43C-421E-B5B5-943B0C79B592/Documents/Yudi Seven.pdf"
let document: PDFKDocument = PDFKDocument(contentsOfFile: pdfUrl, password: nil)
viewer.loadDocument(document)
}
}
}
Goto PDFKBasicPDFViewer.m disable the line(line 247) that highlighted in the first image and run the project....
Output: