简体   繁体   English

Xcode-Swift; 向启动屏幕添加声音效果

[英]Xcode - Swift; adding sound effects to launch screen

Just really quickly wanted to enquire about a minor issue i'm having with trying to get a sound effect playing within my launch-screen of my swift application. 只是很快,我想询问一个小问题,我想在我的swift应用程序的启动屏幕中播放声音效果。 I'm more-so confused in regards to where I'm meant to declare my AVAudio player (in my view controller or Appdelegate); 关于在哪里声明我的AVAudio播放器(在我的视图控制器或Appdelegate中)的含义,我更加困惑。 but haven't had success in either methods. 但两种方法都没有成功。 Here is what i've currently got within my appDelegate file 这是我目前在我的appDelegate文件中得到的

import UIKit
import AVFoundation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var audioPlayer = AVAudioPlayer()

        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            // Override point for customization after application launch.

            self.window = UIWindow(frame: UIScreen.main.bounds)
            self.window!.backgroundColor = UIColor(red: 9/255, green: 4/255, blue: 68/255, alpha: 1)
            self.window!.makeKeyAndVisible()

            // rootViewController from StoryBoard
            let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let navigationController = mainStoryboard.instantiateViewController(withIdentifier: "navigationController")
            self.window!.rootViewController = navigationController

            // logo mask
            navigationController.view.layer.mask = CALayer()
            navigationController.view.layer.mask!.contents = UIImage(named: "logo.png")!.cgImage
            navigationController.view.layer.mask!.bounds = CGRect(x: 0, y: 0, width: 60, height: 60)
            navigationController.view.layer.mask!.anchorPoint = CGPoint(x: 0.5, y: 0.5)
            navigationController.view.layer.mask!.position = CGPoint(x: navigationController.view.frame.width / 2, y: navigationController.view.frame.height / 2)

            // logo mask background view
            let maskBgView = UIView(frame: navigationController.view.frame)
            maskBgView.backgroundColor = UIColor.white
            navigationController.view.addSubview(maskBgView)
            navigationController.view.bringSubview(toFront: maskBgView)

            // logo mask animation
            let transformAnimation = CAKeyframeAnimation(keyPath: "bounds")
            transformAnimation.delegate = self as? CAAnimationDelegate
            transformAnimation.duration = 1
            transformAnimation.beginTime = CACurrentMediaTime() + 1 //add delay of 1 second
            let initalBounds = NSValue(cgRect: (navigationController.view.layer.mask!.bounds))
            let secondBounds = NSValue(cgRect: CGRect(x: 0, y: 0, width: 50, height: 50))
            let finalBounds = NSValue(cgRect: CGRect(x: 0, y: 0, width: 2000, height: 2000))
            transformAnimation.values = [initalBounds, secondBounds, finalBounds]
            transformAnimation.keyTimes = [0, 0.5, 1]
            transformAnimation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut), CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)]
            transformAnimation.isRemovedOnCompletion = false
            transformAnimation.fillMode = kCAFillModeForwards
            navigationController.view.layer.mask!.add(transformAnimation, forKey: "maskAnimation")

            // logo mask background view animation
            UIView.animate(withDuration: 0.1,
                           delay: 1.35,
                           options: UIViewAnimationOptions.curveEaseIn,
                           animations: {
                            maskBgView.alpha = 0.0
            },
                           completion: { finished in
                            maskBgView.removeFromSuperview()
            })

            // root view animation
            UIView.animate(withDuration: 0.25,
                           delay: 1.3,
                           options: UIViewAnimationOptions(),
                           animations: {
                            self.window!.rootViewController!.view.transform = CGAffineTransform(scaleX: 1.05, y: 1.05)
            },
                           completion: { finished in
                            UIView.animate(withDuration: 0.3,
                                           delay: 0.0,
                                           options: UIViewAnimationOptions(),
                                           animations: {
                                            self.window!.rootViewController!.view.transform = CGAffineTransform.identity
                            },
                                           completion: nil
                            )

                            do {
                                self.audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: "startup", ofType: "wav")!))
                                self.audioPlayer.prepareToPlay()
                            }
                            catch {
                                print(error)
                            }
            })

            return true

    }



    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


}

The method I prefer to use is declaring 我更喜欢使用的方法是声明

var audioPlayer = AVAudioPlayer()

in the AppDelegate (as you did in your code). 在AppDelegate中(就像在代码中一样)。

And having a method for playing the audio 并有一种播放音频的方法

func playSound(file:String, ext:String) -> Void {
    do {
        let url = URL.init(fileURLWithPath: Bundle.main.path(forResource: file, ofType: ext)!)
        audioPlayer = try AVAudioPlayer(contentsOf: url)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    } catch let error {
        NSLog(error.localizedDescription)
    }
}

This way, you can call 这样你可以打电话

playSound(file: "startup", ext: "wav")

to play this sound (and other sounds too) anywhere and anytime in your app, with minimal code duplication. 可以在您的应用程序中随时随地播放此声音(以及其他声音),同时减少代码重复。

I have faced some similar issues when I wanted to do a handshake call at the splash. 我想在启动时进行一次握手呼叫时遇到了类似的问题。 But according to Apple UX, the user should be able to go to landing as fast as possible. 但是根据Apple UX,用户应该能够尽快上岸。

The launch screen prepares your view and application before. 启动屏幕之前会准备好视图和应用程序。 We cant control it. 我们无法控制它。 But the launch screen time can be reduced if we dont do much heavy task in the landing view controller or do that in a separate thread. 但是,如果我们不执行着陆视图控制器中的繁重任务或在单独的线程中执行此任务,则可以减少启动屏幕的时间。 This way launch screen time is reduced. 这样可以减少启动屏幕的时间。

To do that sound effect, you can make a initial VC and call replicate the same UI as launchscreen so transition wont be visible. 要实现这种音效,您可以制作一个初始VC,并调用与启动屏幕相同的UI进行复制,以使过渡不会可见。 And at there you can perform your Audio stuff in viewDidLoad() or viewDidAppear(animated:Bool) 在这里,您可以在viewDidLoad()viewDidAppear(animated:Bool)执行音频操作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM