gpt4 book ai didi

ios - 如何从独立类获取通知(Swift 3)

转载 作者:行者123 更新时间:2023-11-28 06:21:59 24 4
gpt4 key购买 nike

我想在观察者收到另一个类中的通知后立即调用一个类中的方法。问题是我不能从一个类调用另一个类,因为那时我会得到递归调用。

1) 带有 Player 实例的 Controller 类:

//  PlayerController.swift
// player

import UIKit
import MediaPlayer

class NowPlayingController: NSObject {

var musicPlayer: MPMusicPlayerController {
if musicPlayer_Lazy == nil {
musicPlayer_Lazy = MPMusicPlayerController.systemMusicPlayer()
let center = NotificationCenter.default
center.addObserver(
self,
selector: #selector(self.playingItemDidChange),
name: NSNotification.Name.MPMusicPlayerControllerNowPlayingItemDidChange,
object: musicPlayer_Lazy)
musicPlayer_Lazy!.beginGeneratingPlaybackNotifications()
}

return musicPlayer_Lazy!
}

//If song changes
func playingItemDidChange(notification: NSNotification) {
//somehow call updateSongInfo() method from 2nd class
}

//Get song metadata
func getSongData() -> (UIImage, String?, String?) {
let nowPlaying = musicPlayer.nowPlayingItem

//...some code
return (albumImage, songName, artistAlbum)
}

func updateProgressBar() -> (Int?, Float?){
let nowPlaying = musicPlayer.nowPlayingItem
var songDuration: Int?
var elapsedTime: Float?

songDuration = nowPlaying?.value(forProperty: MPMediaItemPropertyPlaybackDuration) as? Int
elapsedTime = Float(musicPlayer.currentPlaybackTime)

return(songDuration, elapsedTime)
}
}

2) View controller 应该在 Player Controller 收到通知时更新

//  MainViewController.swift
// player

import UIKit

class MainViewController: UIViewController {

let playerController = PlayerController()
@IBOutlet weak var albumView: UIImageView!
@IBOutlet weak var songLabel: UILabel!
@IBOutlet weak var artistAlbum: UILabel!

override func viewDidLoad() {
super.viewDidLoad()

//Start updating progress bar
Timer.scheduledTimer(timeInterval: 0.5,
target: self,
selector: #selector(MainViewController.updateProgressBar),
userInfo: nil,
repeats: true)
}

private func updateSongInfo(){
(albumView.image!, songLabel.text, artistAlbum.text) = playerController.getSongData()
}

private func updateProgressBar(){
(progressBar.maximumValue, progressBar.value) = playerController.playingItemProgress()
}
}

Swift 3 的解决方案:

在 NowPlayingController 中:

let newSongNotifications = NSNotification(name:NSNotification.Name(rawValue: "updateSongNotification"), object: nil, userInfo: nil)

func playingItemDidChange(notification: NSNotification) {
NotificationCenter.default.post(newSongNotifications as Notification)
}

在其他 Controller 中:

override func viewDidLoad() {
super.viewDidLoad()

NotificationCenter.default.addObserver(self, selector: #selector(self.updateSongInfo), name: NSNotification.Name(rawValue: "updateSongNotification"), object: nil)
}

最佳答案

您可以在您需要的自定义对象中发布通知:

    let notification = NSNotification(name:"doSomethingNotification", object: nil, userInfo: nil)
NotificationCenter.defaultCenter.postNotification(notification)

然后在您想要执行某些操作以响应此通知的其他 View Controller 中,您告诉它观察 viewDidLoad() 中的通知。您传入的选择器是您希望在收到通知时执行的方法。

    override func viewDidLoad(){
super.viewDidLoad()

NotificationCenter.addObserver(self, selector: #selector(self.doSomething), name: "doSomethingNotification", object: nil)
}

关于ios - 如何从独立类获取通知(Swift 3),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43134115/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com