我正在尝试在SwiftUI列表中创建自定义按钮。我希望它具有蓝色和白色文本背景,重要的是要保持蓝色并在按下时达到50%的不透明度,而不是默认的灰色。
我尝试使用自定义的ButtonStyle,但是当我这样做时,按钮的可点击区域被缩小为仅标签本身。如果我点击单元格的任何其他部分,颜色不会改变。如果我删除ButtonStyle,则在单元格上的任意位置轻按即可
如何解决此问题,以便获得自定义颜色,包括点击时的颜色,但整个单元仍可轻敲?
import SwiftUI
struct BlueButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.font(.headline)
.foregroundColor(configuration.isPressed ? Color.white.opacity(0.5) : Color.white)
.listRowBackground(configuration.isPressed ? Color.blue.opacity(0.5) : Color.blue)
}
}
struct ExampleView: View {
var body: some View {
NavigationView {
List {
Section {
Text("Info")
}
Section {
Button(action: {print("pressed")})
{
HStack {
Spacer()
Text("Save")
Spacer()
}
}.buttonStyle(BlueButtonStyle())
}
}
.listStyle(GroupedListStyle())
.environment(\.horizontalSizeClass, .regular)
.navigationBarTitle(Text("Title"))
}
}
}
struct ExampleView_Previews: PreviewProvider {
static var previews: some View {
ExampleView()
}
}
答案 0 :(得分:7)
在标准变体列表中,List会拦截并处理轻敲检测的内容区域,在您的自定义样式中,默认情况下,它是由不透明区域定义的,不透明区域只是您的情况下的文本,因此更正的样式是
通过Xcode 11.4 / iOS 13.4测试
public class RelayAsyncCommand<T> : RelayCommand<T>
{
private bool _isExecuting = false;
public event EventHandler Started;
public event EventHandler Ended;
public bool IsExecuting
{
get { return _isExecuting; }
private set
{
if (value != _isExecuting)
{
_isExecuting = value;
CommandManager.InvalidateRequerySuggested();
}
}
}
public RelayAsyncCommand(Action<T> execute, Predicate<T> canExecute)
: base(execute, canExecute)
{
}
public RelayAsyncCommand(Action<T> execute)
: base(execute)
{
}
public override bool CanExecute(object parameter)
{
return ((base.CanExecute(parameter)) && (!IsExecuting));
}
public override void Execute(object parameter)
{
try
{
IsExecuting = true;
Started?.Invoke(this, EventArgs.Empty);
Task task = Task.Factory.StartNew(() =>
{
_execute((T)parameter);
});
task.ContinueWith(t =>
{
OnRunWorkerCompleted(EventArgs.Empty);
}, TaskScheduler.FromCurrentSynchronizationContext());
}
catch (Exception ex)
{
OnRunWorkerCompleted(new RunWorkerCompletedEventArgs(null, ex, true));
}
}
private void OnRunWorkerCompleted(EventArgs e)
{
IsExecuting = false;
Ended?.Invoke(this, e);
}
}
和用法,仅
struct BlueButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.font(.headline)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.contentShape(Rectangle())
.foregroundColor(configuration.isPressed ? Color.white.opacity(0.5) : Color.white)
.listRowBackground(configuration.isPressed ? Color.blue.opacity(0.5) : Color.blue)
}
}
甚至
Button(action: {print("pressed")})
{
Text("Save")
}.buttonStyle(BlueButtonStyle())