Post

Replies

Boosts

Views

Activity

.keyboardShortcut on Button in Swift doesn't properly rerender unless button.label changes
here is minimal reproducible example: import SwiftUI struct ContentView: View {   @State var options = ["1","2","3","4"]   @State var option = "1"   var body: some View {     ForEach(options, id: \.self) { item in       Button(item, action: {         self.option = item       })     }     ChildView(model: .init(option: option))   } } class ChildViewModel: ObservableObject {   @Published var option: String   init(option: String) {     self.option = option   } } struct ChildView: View {   @ObservedObject var model: ChildViewModel   var body: some View {     Text(model.option)     Button("Tab", action: {       print("Option: \(model.option)")     })     .keyboardShortcut("f")   } } struct ContentView_Previews: PreviewProvider {   static var previews: some View {     ContentView()   } } Here is steps to reproduce: click "2" item click "Tab" Button, which will prints "Option: 2" press Cmd+F, which will prints "Option: 1" step(3) is unexpected behavior, since it has to print "Option: 2" If you change Button("Tab") into Button("Tab (model.option)"), step 3 will produce proper result of printing "Option: 2" So i assume this is issue of keyboardShortcut not properly referencing "latest" action - unless "label" of button changes, keyboardShortcut does not use latest "action" that is given. but as you can see from example, clicking button will result calling latest action
4
2
721
Dec ’22
Putting custom view in .contextMenu() on SwiftUI creates permanent memory leak
here is a minimal reproducible example, on macOS struct ContextMenuTest1: View { @State var visible: Bool = true var body: some View { Button(action: { self.visible.toggle() }, label: { Text("ContextMenuTest2 Toggle") }) if self.visible { ChildView() } } struct ChildView: View { class Model: ObservableObject { init() { print("Model Created") } deinit { print("This will never be called") } func someAction() { } } var body: some View { Text("Text That has Context Menu") .contextMenu { ContextMenu() } } struct ContextMenu: View { @StateObject var model: Model = .init() var body: some View { Button(action: { self.model.someAction() }, label: { Text("Context Menu Button 1") }) } } } } step to reproduce : right click on Text("Text That has Context Menu") to open contextMenu() turn off the contextMenu click "ContextMenuTest2 Toggle" This should have destroyed both ChildView and ChildView.ContextMenu, thus should have deallocated ChildView.Model but ChildView.Model.deinit never be called. I understand .contextMenu() document show examples of putting Button directly, but it doesn't mention or block attempts of putting custom view directly like this - in which case, Button.action closure it permanent memory leaked. unless you kill the application hope that clairify the bug, thanks!
0
0
386
Oct ’23