You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift View中实现点击切换图标的Button技术咨询

SwiftUI按钮点击无法切换图标问题解决

问题描述

想在SwiftUI View中实现一个点击切换图标的Button,已确认点击按钮时my_player.isPlaying会在true和false之间切换,但当前代码始终显示pause图标。此前在ViewController中用IBOutlet实现过类似功能,首次编写SwiftUI代码遇到图标不更新的问题。

原代码片段:

struct myview: View {
@EnvironmentObject var my_player: MusicPlayer

var body: some View {
    let play_icon = UIImage(imageLiteralResourceName: "play.png")
    let pause_icon = UIImage(imageLiteralResourceName: "pause.png")
    let button_size : CGFloat = 60
    VStack {
            Button(action: {
                my_player.play_pause_music()
            }) {
                HStack {
                    Image(uiImage: my_player.isPlaying ? pause_icon : play_icon)
                        .resizable()
                        .scaledToFit()
                        .frame(width: button_size)
                }
            }
        }
    }
}

解决建议

  • 确保isPlaying是响应式属性:SwiftUI依赖ObservableObject的@Published标记来感知属性变化并触发View重绘。检查你的MusicPlayer类,必须将isPlaying标记为@Published,否则即使值变化,View也不会更新。示例:

    class MusicPlayer: ObservableObject {
        @Published var isPlaying = false
        
        func play_pause_music() {
            isPlaying.toggle()
            // 这里添加实际的播放/暂停逻辑
        }
    }
    
  • 优化资源定义位置:将图片资源和按钮尺寸的定义移到body外部,避免每次View重绘时重复创建对象,提升性能同时让代码更规范:

    struct MyView: View { // Swift类型名规范首字母大写
        @EnvironmentObject var my_player: MusicPlayer
        
        private let playIcon = UIImage(imageLiteralResourceName: "play.png")
        private let pauseIcon = UIImage(imageLiteralResourceName: "pause.png")
        private let buttonSize: CGFloat = 60
        
        var body: some View {
            VStack {
                Button(action: {
                    my_player.play_pause_music()
                }) {
                    Image(uiImage: my_player.isPlaying ? pauseIcon : playIcon)
                        .resizable()
                        .scaledToFit()
                        .frame(width: buttonSize)
                }
            }
        }
    }
    
  • 确认环境对象已正确注入:确保你已经在View层级的根节点通过.environmentObject(_:)注入了MusicPlayer的实例,比如:

    // 在SceneDelegate或App入口处
    let player = MusicPlayer()
    let contentView = MyView().environmentObject(player)
    

内容的提问来源于stack exchange,提问作者UpNorth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:28:24