Z S
Z S

Reputation: 7491

SwiftUI: double-click in Table row on macOS

I am using a Table with multiple columns (new in SwiftUI 3.0) to show my data, and I want to be able to double-click on the row to open a new window with another view (with information passed in through the row that was double-clicked). What's the simplest way to achieve that? I can't seem to find any way to handle double-click on a selected row.

This is my current code to display the table:

      Table(item, selection: $selection, sortOrder: $sorting) {
            TableColumn("RecordName") { itemModel in
                Text("\(itemModel.recordName ?? "no name")")
            }
            TableColumn("Model") { item in
                Text("\(item.deviceName ?? "no model")")
            }
            TableColumn("CreatedAt") { item in
                Text("\(item.deviceCreatedDate?.formatted() ?? "no date")")
            }
      }

How do I handle a double-select action? Also, how do I open another view in another "window"?

Upvotes: 6

Views: 1989

Answers (2)

Yakuhzi
Yakuhzi

Reputation: 1269

Apple introduced a new context menu modifier contextMenu(forSelectionType:menu:primaryAction:) with SwiftUI 4 at WWDC 2022. With this, a primaryAction can be provided that is performed when the user double clicks on a Table row.

@State private var selection: ItemModel.ID?

var body: some View {
    Table(items, selection: $selection, sortOrder: $sortOrder) {
        TableColumn("RecordName", value: \.recordName)
        TableColumn("Model", value: \.model)
        TableColumn("CreatedAt", value: \.createdAt)
    }
    .contextMenu(forSelectionType: ItemModel.ID.self) { items in
        // ...
    } primaryAction: { items in
        // This is executed when the row is double clicked
    }
}

Upvotes: 6

Hezi Shahmoon
Hezi Shahmoon

Reputation: 388

Using the onTapGesture with the count of 2 is actually handling double clicking. Here is a simplified example.

//
//  ContentView.swift
//  SUITable
//
//  Created by Hezi Shahmoon on 10/02/2022.
//

import SwiftUI

struct ContentView: View {
    @State private var items: [ItemModel] = Array(0...100).map { ItemModel(id: $0, recordName: "item \($0)", age: $0) }
    @State private var selection = Set<ItemModel.ID>()
    @State private var sorting = [KeyPathComparator(\ItemModel.age)]
    
    @State private var showingAlert = false
     
    var body: some View {
        Table(items, selection: $selection, sortOrder: $sorting) {
               TableColumn("RecordName") { itemModel in
                   Text("\(itemModel.recordName)")
                       .onTapGesture(count: 2, perform: {
                           showingAlert = true
                       })
                       .alert("Important message", isPresented: $showingAlert) {
                                   Button("OK", role: .cancel) { }
                       }
               }
         }
    }
}

struct ItemModel: Identifiable {
    var id: Int
    var recordName: String
    var age: Int
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Upvotes: 0

Related Questions