iT邦幫忙

2025 iThome 鐵人賽

DAY 26
0

提示聲頁面 SoundViewController

這個頁面主要的功能是:

  • 顯示所有可選擇的提示聲(以表格方式呈現)。
  • 點擊其中一項時立即播放音效。
  • 通知上一頁(新增鬧鐘頁面)使用者選擇了哪個聲音。

為了達成這些功能,我們先建立一個協定,再實作整個控制器的邏輯。

協定設計

我們使用 DelegateSoundViewController 能把「使用者選擇的音效」傳回給呼叫它的頁面:

protocol SoundViewControllerDelegate: AnyObject {
    func didSelectSound(_ soundName: String)
}

屬性設定

接著在 SoundViewController 中定義需要的屬性


    weak var delegate: SoundViewControllerDelegate?
    let sounds = ["馬林巴琴", "鬼畜", "雷達", ]
    var selectedSoundIndex: Int = 0
    var audioPlayer: AVAudioPlayer?
    var currentSelectedSound: String?

說明:
delegate:用來通知上一頁使用者的選擇。
sounds:音效名稱清單。
selectedSoundIndex:目前被選擇的音效位置,用來顯示打勾符號。
audioPlayer:播放音效的物件。
currentSelectedSound:進入此頁時的預設音效。

畫面初始化

當頁面載入時,我們先設定 UI,並根據目前的音效名稱顯示正確的選取狀態。

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        if let currentSound = currentSelectedSound,
           let index = sounds.firstIndex(of: currentSound) {
            selectedSoundIndex = index
        }
    }
 
    func setupUI() {
        title = "提示聲"
        tbvSound.register(UINib(nibName: "SoundTableViewCell", bundle: nil), forCellReuseIdentifier: "SoundTableViewCell")
        tbvSound.delegate = self
        tbvSound.dataSource = self
    }

播放音效功能

點擊音效後,頁面會立刻播放出選擇的聲音。
為了達成這點,我們使用 AVAudioPlayer:

    // 播放音效
    func playSound(named name: String) {
       guard let url = Bundle.main.url(forResource: name, withExtension: "mp3") else { return }
       do {
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            audioPlayer?.play()
        } catch {
            print("無法播放音效: \(error.localizedDescription)")
        }
    }
}

Tips:音效檔需事先加入專案(例如:馬林巴琴.mp3)。

表格邏輯 TableView

最後,我們讓 SoundViewController 實作表格代理與資料來源:

    extension SoundViewController: UITableViewDelegate, UITableViewDataSource {
        // 返回音效數量
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return sounds.count
        }
        // 返回每個音效的cell
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "SoundTableViewCell", for: indexPath) as! SoundTableViewCell
            cell.lbSound.text = sounds[indexPath.row]
            cell.accessoryType = indexPath.row == selectedSoundIndex ? .checkmark : .none
            return cell
        }
        // 當選擇某個音效時,更新選擇的音效並播放
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                selectedSoundIndex = indexPath.row
                delegate?.didSelectSound(sounds[selectedSoundIndex])
                tableView.reloadData()
                playSound(named: sounds[selectedSoundIndex])
            }
    }

結語

這樣我們今天就成功把聲音的功能給完成了喔。


上一篇
Day 25 時鐘 4
下一篇
Day 27 天氣API 1
系列文
Swift一下就會了27
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言