skip to Main Content

I am trying to make Menu using swiftUI in MacOS application.

Based on this:

Reference Link of Code

Another Reference Link

I am using this specific code

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-item entries:

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")})
}

Menu Image

If you look at the image "Two" menu item is not aligned with "One" and "Three" menu options, as there is an image of checkmark is there for options "One" & "Thrree".
I tried Spacer with Minimum width (and some other options) but doesn’t seem to work and align "Two" with "One" & "Three"

Can you recommend anything which can resolve this issue and make alignment of "Two" inline with "One" & "Three" ?

2

Answers


  1. Here is possible approach – just make it invisible instead of removing:

    Image("checkmark")
        .resizable()
        .renderingMode(.template)
        .scaledToFit()
        .opacity(self.isSelected ? 1 : 0)
        .id(self.isSelected ? 1 : 2)        // << try to add !!
    
    Login or Signup to reply.
  2. This doesn’t quite answer the question you asked, but instead goes to what I think is your goal. Instead of buttons, try toggles, like this:

    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")
        }
    }
    

    Here’s how it looks on macOS:

    A menu with four items, two of which have checkmarks. The titles all line up with the checkmarks in a leading gutter.

    And here’s iOS:

    The same menu on iOS. The titles still line up, and the checkmarks are in a leading gutter.

    The item titles all line up, whether toggle or button, and the checkmarks extend the menu out in the leading direction. This doesn’t let you use arbitrary images in your menu items, but it works well for the specific case of checkmarks indicating toggled menu items.

    Creating the bindings just-in-time like that isn’t great coding style, but it’s functional for a snippet like this, and makes it clear what is going on. For these, I have hard-coded the conditions, but you can get arbitrarily fancy in the binding get and set methods.

    I have some code like this to let me toggle a few bools in a Core Data object representing data pulled from a remote server. In my bindings’ get methods, I return the value of a property of the object which has been passed to my view. In the bindings’ set methods, I do a little NSManagedObjectContext jig to create a private copy of the object where I set the property I’m working with to not itself, then I pass the private object to a method in another object which writes the data to the remote server and refreshes the real copy in the persistent store.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search