【问题标题】:How to align SwiftUI menu-item with checkmark in macOS?如何将 SwiftUI 菜单项与 macOS 中的复选标记对齐?
【发布时间】:2021-08-09 12:02:12
【问题描述】:

我正在尝试在 MacOS 应用程序中使用 swiftUI 制作菜单。

基于此:

Reference Link of Code

Another Reference Link

我正在使用这个特定的代码

struct SelectionRow: View {
    var title: String
    var isSelected: Bool
    var action: () -> Void

    var body: some View {
        Button(action: self.action) {
            HStack {
                if self.isSelected {
                    Image("checkmark")
                        .resizable()
                        .renderingMode(.template)
                        .scaledToFit()
                } else {
                    //FIXME: What to add here ???!!! <-- Need to add solution here I believe
                }
                Text(self.title)
                    //.frame(alignment: .trailing). <-- Not effective
            }
        }.foregroundColor(Color.black)
    }
}

菜单项条目:

Menu("Example Menu"){
    SelectionRow(title: "One", isSelected: true, action: { print("hello world")})
    SelectionRow(title: "Two", isSelected: false, action: { print("hello world")})
    SelectionRow(title: "Three", isSelected: true, action: { print("hello world")})
}

如果您查看图像“二”菜单项与“一”和“三”菜单选项不对齐,因为选项“一”和“三”有一个复选标记图像。 我尝试了具有最小宽度的 Spacer(以及其他一些选项),但似乎不起作用并将“二”与“一”和“三”对齐

您能推荐任何可以解决此问题并使“二”与“一”和“三”对齐的方法吗?

【问题讨论】:

  • 只需为复选标记图像设置框架,如果未选中则添加具有相同框架的空视图
  • 试过了,用EmptyView().frame(width: 30),Image用同一个frame,还是不行。不知道为什么。可能是菜单不接受它

标签: swift xcode macos swiftui


【解决方案1】:

这并不能完全回答您提出的问题,而是针对我认为您的目标。尝试切换按钮,而不是按钮,如下所示:

Menu("Example Menu") {
    let oneBinding = Binding<Bool>(
        get: { return true },
        set: { _,_ in } )
    Toggle(isOn: oneBinding) {
        Text("One")
    }

    Button {
        print("Two as a Button")
    } label: {
        Text("Two as a Button")
    }

    let twoBinding = Binding<Bool>(
        get: { return false },
        set: { _,_ in } )
    Toggle(isOn: twoBinding) {
        Text("Two as a Toggle")
    }

    let threeBinding = Binding<Bool>(
        get: { return true },
        set: { _,_ in } )
    Toggle(isOn: threeBinding) {
        Text("Three")
    }
}

这是它在 macOS 上的外观:

这里是 iOS:

项目标题全部排列,无论是切换还是按钮,并且复选标记将菜单沿前导方向扩展。这不允许您在菜单项中使用任意图像,但它适用于指示切换菜单项的复选标记的特定情况。

像这样即时创建绑定并不是伟大的编码风格,但它对于像这样的 sn-p 来说是有用的,并且可以清楚地说明发生了什么。对于这些,我已经对条件进行了硬编码,但是您可以在绑定 get 和 set 方法中任意花哨。

我有一些这样的代码可以让我在代表从远程服务器提取的数据的 Core Data 对象中切换几个布尔值。在绑定的 get 方法中,我返回已传递给我的视图的对象的属性值。在绑定的设置方法中,我做了一点 NSManagedObjectContext 夹具来创建对象的私有副本,在该副本中我将正在使用的属性设置为不是自身,然后我将私有对象传递给另一个对象中的方法,该方法写入数据到远程服务器并刷新持久存储中的真实副本。

【讨论】:

  • 就是这样。此外,如果您不需要切换(用于多个同时选择)但从多个选项中选择一个,您可以在菜单中使用Picker。也可以作为子菜单或部分...
【解决方案2】:

这是可能的方法 - 只需使其不可见而不是删除:

Image("checkmark")
    .resizable()
    .renderingMode(.template)
    .scaledToFit()
    .opacity(self.isSelected ? 1 : 0)
    .id(self.isSelected ? 1 : 2)        // << try to add !!

【讨论】:

  • 我尝试了同样的方法,但它似乎不起作用,菜单不允许更改图像不透明度,(与问题无关:我实际上也尝试更改图像的颜色,这似乎也不起作用)
  • 尝试使用 .id 强制重新创建,如更新的快照所示
猜你喜欢
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-30
相关资源
最近更新 更多