RussellHarrower
RussellHarrower

Reputation: 6820

Custom Button style (SwiftUI) tvOS

So I have a custom button class (so I could remove the background that was behind all my logos.)

But now the zoom does not work / activate when a user is hovered over the button - which means that they have no idea what button they are on.

I am wondering how do I add the ability to increase the buttons size (width & height) when the remote is over or on the button?


struct RedRoundButton: ButtonStyle {

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

}

and the button code

 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)
                                                   

I have worked out that I can use this

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

but it won't scale the buttons

full code

//
//  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()
    }
}

Upvotes: 1

Views: 3346

Answers (1)

Adam
Adam

Reputation: 5145

Apple’s recommended solution is to use the new CardButtonStyle button style, which removes the usual padding but keeps the tvOS hover effects:

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

However, this still applies a round-rect button background, which doesn’t look good with your Circle background.

I’d recommend updating your design so you can use CardButtonStyle. Button manages its own focus state, so you can’t override or wire-up anything to it. And on tvOS you can’t make your own button from scratch because there is no onTap/onClick event. Your only other real option is to build a custom button in UIKit so you can avoid the limits of SwiftUI on tvOS.

Upvotes: 3

Related Questions