最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

macos - How to select SwiftUI Table item on single click? - Stack Overflow

programmeradmin2浏览0评论

I have a SwiftUI Table on macOS. (I'm NOT using a List.) I want it to behave the same as a Cocoa table: when a user clicks on a row, focus should shift to the table AND the clicked row should be selected. Right now, the table is gaining focus after one click, but the selection isn't being set. It takes another click for that to happen. Quite annoying.

    Table(tableModel.roads, selection: $tableModel.selectedRoadID) {
        TableColumn("ED") { road in
            Text(road.district)
        }
        .width(35)
        
        TableColumn("Road") { road in
            Text(road.name)
        }
    }
    .frame(height: nil) // Adjust height as needed

I tried adding .focused and an .onTapGesture setting the focus state, but the behavior didn't change.

    @FocusState private var roadsTableFocused: Bool

// ...

    .focused($roadsTableFocused)
    .onTapGesture {
        roadsTableFocused = true
    }

Thanks in advance for your help!


Update: Thanks to Sweeper for the question. This has something to do with the @Observable model class I'm using. When I use a @State variable in the same View class for the TextField, it works fine. Same when I switch to the table from any non-TextField widgets, even though they're also bound to state variables in the model class. Here's an MRE of the issue in the form of a macOS SwiftUI Playground application:

ContentView.swift

import AppKit
import SwiftUI

struct Road: Identifiable {
    let id: Int
    let name: String
    let district: String
}

@Observable class TableModel {
    var observableFieldValue: String = ""
}

struct ContentView: View {
    @State private var tableModel: TableModel
    @State private var selectedRoadID: Road.ID?
    @State private var localFieldValue: String = ""
    @State private var roads: [Road] = [
        Road(id: 1, name: "Market", district: "5"),
        Road(id: 2, name: "Howard", district: "5"),
        Road(id: 3, name: "Gough", district: "5"),
        Road(id: 4, name: "Click Here", district: "5"),
    ]

    init() {
        let viewModel = TableModel()
        _tableModel = State(wrappedValue: viewModel)
    }
    
    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            TextField("Observable binding", text: $tableModel.observableFieldValue)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            TextField("ContentView binding", text: $localFieldValue)
                .textFieldStyle(RoundedBorderTextFieldStyle())

            Table(roads, selection: $selectedRoadID) {
                TableColumn("ED") { road in
                    Text(road.district)
                }
                .width(35)
                
                TableColumn("Road") { road in
                    Text(road.name)
                }
            }
        }
        .frame(width: 300, height: 220, alignment: .leading)
    }
}

#Preview {
    ContentView()
}

Update 2: I've made a video of what I'm seeing. I'm on macOS 15.2 (24C101) using Xcode 16.2 (16C5032a). I've built a full test application using the above code, slightly modified from before to remove the Playground.

Is it really the case that no one else is seeing this behavior?

发布评论

评论列表(0)

  1. 暂无评论