1

我有一个 SwiftUI,它在HStack. 这些按钮有一个图标和一些文本,垂直布局。我遇到了按钮可能变得太宽的问题:HStack 超出了视图本身的范围。例如,如果“全部下载”按钮将其文本放在两行上,那将是合乎逻辑的,但它没有这样做。

预览示例:

在此处输入图像描述

如您所见,第一个版本有问题,三个按钮不再适合。但即使在第二个示例中,圆角也没有完全显示 - 只有第三个示例 100% 正确显示。

代码:

import SwiftUI

struct TransferDetailsButtonsView: View {
  enum ButtonType: Hashable {
    case share
    case download
    case delete

    fileprivate var imageName: String {
      switch self {
        case .share:
          return "icon-share"
        case .download:
          return "icon-download"
        case .delete:
          return "icon-delete"
      }
    }

    fileprivate var title: String {
      switch self {
        case .share:
          return "Share"
        case .download:
          return "Download all"
        case .delete:
          return "Delete"
      }
    }
  }

  /// The button types you want to show
  var buttonTypes: [ButtonType] = [.share, .download, .delete]

  /// The action for the buttons
  var action: (ButtonType) -> Void = { _ in }

  var body: some View {
    HStack(spacing: 0) {
      Spacer(minLength: 20)
        .frame(maxWidth: .infinity)

      ForEach(buttonTypes, id: \.self) { button in
        Button {
          action(button)
        } label: {
          VStack(spacing: 8) {
            Image(button.imageName)
            Text(button.title)
              .lineLimit(nil)
          }
          .fixedSize()
        }

        Spacer(minLength: 20)
          .frame(maxWidth: .infinity)
      }
    }
    .padding(.vertical, 12)
    .foregroundColor(.white)
    .background(RoundedRectangle(cornerRadius: 16).fill(.blue))
  }
}

struct TransferDetailsButtonsView_Previews: PreviewProvider {
  static var previews: some View {
    Group {
      TransferDetailsButtonsView()
        .frame(width: 260)
        .previewLayout(.sizeThatFits)

      TransferDetailsButtonsView()
        .frame(width: 300)
        .previewLayout(.sizeThatFits)

      TransferDetailsButtonsView()
        .frame(width: 420)
        .previewLayout(.sizeThatFits)
    }
  }
}

我怎样才能使它HStack不超出整体范围,而是将多行文本用于按钮文本?

4

1 回答 1

1

fixedSize()让它HStack超出了它的界限。您希望 Texts 填充可用空间,然后 SwiftUI 将尝试中断单词。如果容器太小,它会在单词中中断,因此您需要注意这一点,260 大约是它可以使用此字体大小的最小尺寸。

这是我想出的,修改为可以使用 SF 符号运行。您需要在文本之间进行一些填充,否则它们将在某些大小的容器中相互对齐。

struct TransferDetailsButtonsView: View {
    enum ButtonType: Hashable {
        case share
        case download
        case delete
        
        fileprivate var imageName: String {
            switch self {
            case .share:
                return "square.and.arrow.up.fill"
            case .download:
                return "square.and.arrow.up.fill"
            case .delete:
                return "square.and.arrow.up.fill"
            }
        }
        
        fileprivate var title: String {
            switch self {
            case .share:
                return "Share"
            case .download:
                return "Download all"
            case .delete:
                return "Delete it now"
            }
        }
    }
    
    /// The button types you want to show
    var buttonTypes: [ButtonType] = [.share, .download, .delete]
    
    /// The action for the buttons
    var action: (ButtonType) -> Void = { _ in }
    
    var body: some View {
        HStack(alignment: .top, spacing: 0) {
            ForEach(buttonTypes, id: \.self) { button in
                Button {
                    action(button)
                } label: {
                    VStack(spacing: 8) {
                        Image(systemName: button.imageName)
                        Text(button.title)
                            .frame(maxWidth: .infinity)
                    }
                }
                .padding(.horizontal, 4)
            }
        }
        .padding(.vertical, 12)
        .foregroundColor(.white)
        .background(RoundedRectangle(cornerRadius: 16).fill(.blue))
    }
}

在此处输入图像描述

于 2022-01-18T19:33:26.057 回答