自定义按钮样式 (SwiftUI) tvOS

Custom Button style (SwiftUI) tvOS

所以我有一个自定义按钮 class(这样我就可以删除所有徽标后面的背景。)

但是现在,当用户将鼠标悬停在按钮上时,缩放不起作用/激活 - 这意味着他们不知道他们在哪个按钮上。

我想知道当遥控器位于按钮上方或位于按钮上时,如何添加增加按钮大小(宽度和高度)的功能?


struct RedRoundButton: ButtonStyle {

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .padding(0)
            .font(.title)
            .background( Circle()
                .fill(Color.red))
    }

}

和按钮代码

 Button(action: {
                                                  //  Analytics.logEvent("Station_Change",parameters: [
                                                    //    "name": station.name
                                                    //])
                                                     AdStichrApi.station = station.name
                                                    MusicPlayer.shared.startBackgroundMusic(url:station.listenlive, type: "radio")
                                                   // self.showingDetail.toggle()
                                                   }) {
                                                    
                                                    KFImage(URL(string: station.imageurl)!)
                                                        .resizable()
                                                        .renderingMode(.original)
                                                        .frame(width:geo.size.width / 10, height:geo.size.width / 10)
                                                        .clipShape(Circle())
                                                    .sheet(isPresented: self.$showingDetail) {
                                                       // MediaPlayerView()
                                                            
                                                    }
                                                }
                                                   .buttonStyle(RedRoundButton())
                                                   .frame(width: geo.size.width / 10,height: geo.size.width / 10)
                                                   

我发现我可以使用这个

.focusable(true){isFocused in
                                                        self.focused = true
                                                   }
                                                   .scaleEffect(self.focused ? 1:0)

但它不会缩放按钮

完整代码

//
//  ContentView.swift
//  DRN1
//
//  Created by Russell Harrower on 10/10/20.
//

import SwiftUI
import AVKit
import struct Kingfisher.RoundCornerImageProcessor
import KingfisherSwiftUI


struct ContentView: View {
    @State var showingDetail = false
    @State var stations: [Station] = []
    @State var showDetail = String(false)
    @State var focused = false
    
    
    var body: some View {
        GeometryReader { geo in
            Group {
                
                if self.stations.isEmpty {
                Text("Loading")
                //this must be empty
                //.navigationBarHidden(true)
                      
                }
                else
                {
                    VStack(alignment: .leading){
                        Text("Our Stations")
                        .lineSpacing(30)
                        .padding(5)
                        .font(.system(size: 30, weight: .heavy, design: .default))
                        ScrollView(.horizontal, showsIndicators: false) {
                                            HStack(alignment: .bottom, spacing: 10) {
                                                ForEach(self.stations) { station in
                                                    //return
                                                   Button(action: {
                                                  //  Analytics.logEvent("Station_Change",parameters: [
                                                    //    "name": station.name
                                                    //])
                                                     AdStichrApi.station = station.name
                                                    MusicPlayer.shared.startBackgroundMusic(url:station.listenlive, type: "radio")
                                                   // self.showingDetail.toggle()
                                                   }) {
                                                    
                                                    KFImage(URL(string: station.imageurl)!)
                                                        .resizable()
                                                        .renderingMode(.original)
                                                        .frame(width:geo.size.width / 10, height:geo.size.width / 10)
                                                        .clipShape(Circle())
                                                    .sheet(isPresented: self.$showingDetail) {
                                                       // MediaPlayerView()
                                                            
                                                    }
                                                }
                                                   .buttonStyle(RedRoundButton())
                                                   .focusable(true){isFocused in
                                                        self.focused = true
                                                   }
                                                   .scaleEffect(self.focused ? 1:0)
                                                   .frame(width: geo.size.width / 10,height: geo.size.width / 10)
                                                   
                                                   
                                                
                                            }
                                                
                                            }.frame(height: geo.size.width / 4)
                        }.frame(height: geo.size.width / 4)
                                                    
                    }
                }
            }
        }
                          
                         
                         
            
                            
        .onAppear {
         //   self.navigationViewStyle(StackNavigationViewStyle())
            MusicPlayer.shared.startBackgroundMusic(url: "http://stream.radiomedia.com.au:8006/stream", type: "radio")
            //print(self.showingDetail)
            Api().getStations { (stations) in
                           self.stations = stations
            }
        }
                            
                       
        .onPlayPauseCommand(perform: {
            
            if(MusicPlayer.shared.player?.rate != 0)
            {
                MusicPlayer.shared.player?.pause()
            }
            else{
                MusicPlayer.shared.player?.play()
            }
        })
    
    }
    

}


struct RedRoundButton: ButtonStyle {

   
  
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .padding(0)
            .font(.title)
            .background(Circle()
            .fill(Color.red))
           
            
            
    }

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Apple 推荐的解决方案是使用新的 CardButtonStyle 按钮样式,它删除了通常的填充但保留了 tvOS 悬停效果:

Button(action: {}, label: {
    Text("B")
        .padding()
        .background(Color.red)
        .clipShape(Circle())
})
.buttonStyle(CardButtonStyle())

但是,这仍然应用 round-rect 按钮背景,这与您的 Circle 背景不相配。

我建议更新您的设计,以便您可以使用 CardButtonStyle。按钮管理它自己的焦点状态,所以你不能覆盖或 wire-up 任何东西给它。在 tvOS 上,你不能从头开始制作自己的按钮,因为没有 onTap/onClick 事件。您唯一的其他真正选择是在 UIKit 中构建自定义按钮,这样您就可以避免 SwiftUI 在 tvOS 上的限制。