按钮不会显示禁用的样式
Posted
技术标签:
【中文标题】按钮不会显示禁用的样式【英文标题】:Button won't show disabled styling 【发布时间】:2021-02-15 18:54:04 【问题描述】:我创建了一个结构,通过传递类型和大小参数来设置按钮样式。我希望按钮在禁用时更改样式,但它不起作用。该按钮确实在禁用和启用之间切换,但样式始终是启用的样式。
struct CustomButton: ButtonStyle
enum ButtonStyle
case button, destructive, light
enum ButtonSize
case normal, large, small
@Environment(\.isEnabled) var isEnabled
private var maxWidth : CGFloat
private var padding : CGFloat
private var foreground : Color
private var foregroundDisabled : Color
private var strokeColor : Color
private var strokeDisabled : Color
private var strokeWidth : CGFloat
private var background : Color
private var backgroundDisabled : Color
private var fontSize : Font
init(style: ButtonStyle, size: ButtonSize)
switch size
case .large:
self.maxWidth = .infinity
self.padding = 15.0
self.fontSize = Font.system(.title3, design: .rounded).weight(.bold)
case .small:
self.maxWidth = 200
self.padding = 8.0
self.fontSize = Font.system(.callout, design: .rounded)
default:
self.maxWidth = .infinity
self.padding = 12.0
self.fontSize = Font.system(.body, design: .rounded)
switch style
case .light:
strokeColor = .main
strokeDisabled = .gray
strokeWidth = size == .small ? strokeSmall: strokeLarge
foreground = .main
foregroundDisabled = .gray
background = .clear
backgroundDisabled = .clear
case .destructive:
strokeColor = .destructive
strokeDisabled = .gray
strokeWidth = size == .small ? strokeSmall : strokeLarge
foreground = .destructive
foregroundDisabled = .destructive
background = .clear
backgroundDisabled = .clear
default:
strokeColor = .clear
strokeDisabled = .clear
strokeWidth = 0.0
foreground = .white
foregroundDisabled = .white
backgroundDisabled = .gray
background = .main
func makeBody(configuration: Self.Configuration) -> some View
return configuration.label
.frame(maxWidth: maxWidth)
.font(fontSize)
.foregroundColor(isEnabled ? foreground : Color.red)
.padding(padding)
.background(RoundedRectangle(cornerRadius: roundedCorner)
.strokeBorder(isEnabled ? strokeColor : strokeDisabled, lineWidth: strokeWidth)
.background(isEnabled ? background : backgroundDisabled)
)
.clipShape(RoundedRectangle(cornerRadius: roundedCorner))
.opacity(configuration.isPressed ? 0.8 : 1.0)
.scaleEffect(configuration.isPressed ? 0.98 : 1.0)
它被添加到这样的视图中:
Button(action:
//Some logic here
, label:
Text(NSLocalizedString("Add Group", comment: "button"))
)
.disabled(selections.count < 2) //the button does become disabled (but doesn't change style)
.buttonStyle(CustomButton(style: .button, size: .normal))
【问题讨论】:
这个帖子有帮助吗? ***.com/questions/59169436/… 【参考方案1】:@Environment 没有注入样式,它仅用于视图,所以这里有一个可能的解决方案演示 - 基于内部帮助包装器视图。
struct CustomButton: ButtonStyle
enum ButtonStyle
case button, destructive, light
enum ButtonSize
case normal, large, small
private var maxWidth : CGFloat
private var padding : CGFloat
private var foreground : Color
private var foregroundDisabled : Color
private var strokeColor : Color
private var strokeDisabled : Color
private var strokeWidth : CGFloat
private var background : Color
private var backgroundDisabled : Color
private var fontSize : Font
init(style: ButtonStyle, size: ButtonSize)
switch size
case .large:
self.maxWidth = .infinity
self.padding = 15.0
self.fontSize = Font.system(.title3, design: .rounded).weight(.bold)
case .small:
self.maxWidth = 200
self.padding = 8.0
self.fontSize = Font.system(.callout, design: .rounded)
default:
self.maxWidth = .infinity
self.padding = 12.0
self.fontSize = Font.system(.body, design: .rounded)
switch style
case .light:
strokeColor = .main
strokeDisabled = .gray
strokeWidth = size == .small ? strokeSmall: strokeLarge
foreground = .main
foregroundDisabled = .gray
background = .clear
backgroundDisabled = .clear
case .destructive:
strokeColor = .destructive
strokeDisabled = .gray
strokeWidth = size == .small ? strokeSmall : strokeLarge
foreground = .destructive
foregroundDisabled = .destructive
background = .clear
backgroundDisabled = .clear
default:
strokeColor = .clear
strokeDisabled = .clear
strokeWidth = 0.0
foreground = .white
foregroundDisabled = .white
backgroundDisabled = .gray
background = .main
private struct EnvReaderView<Content: View>: View // << this one !!
let content: (Bool) -> Content
@Environment(\.isEnabled) var isEnabled // read environment
var body: some View
content(isEnabled) // transfer into builder
func makeBody(configuration: Self.Configuration) -> some View
EnvReaderView isEnabled in // now we can use it !!
configuration.label
.frame(maxWidth: maxWidth)
.font(fontSize)
.foregroundColor(isEnabled ? foreground : Color.red)
.padding(padding)
.background(RoundedRectangle(cornerRadius: roundedCorner)
.strokeBorder(isEnabled ? strokeColor : strokeDisabled, lineWidth: strokeWidth)
.background(isEnabled ? background : backgroundDisabled)
)
.clipShape(RoundedRectangle(cornerRadius: roundedCorner))
.opacity(configuration.isPressed ? 0.8 : 1.0)
.scaleEffect(configuration.isPressed ? 0.98 : 1.0)
【讨论】:
以上是关于按钮不会显示禁用的样式的主要内容,如果未能解决你的问题,请参考以下文章
[ATL/WTL]_[初级]_[解决自定义按钮禁用时没有绘制自定义样式-显示黑色矩形框的问题]
[ATL/WTL]_[初级]_[解决自定义按钮禁用时没有绘制自定义样式-显示黑色矩形框的问题]