-
- Notifications
You must be signed in to change notification settings - Fork 29
Open
Labels
bugSomething isn't workingSomething isn't working
Description
macOS Version(s) Used to Build
macOS 13 Ventura
Xcode Version(s)
Xcode 14
Description
The key handles tap with delay if the Кeyboard is in a ScrollView. See the modified KeyboardDemo example below.
The bug only occurs on iOS.
On macOS, the Keyboard in a ScrollView works correctly.
Crash Logs, Screenshots or Other Attachments (if applicable)
Modified ContentView.swift from KeyboardDemo to demonstrate the bug:
import Keyboard import SwiftUI import Tonic let evenSpacingInitialSpacerRatio: [Letter: CGFloat] = [ .C: 0.0, .D: 2.0 / 12.0, .E: 4.0 / 12.0, .F: 0.0 / 12.0, .G: 1.0 / 12.0, .A: 3.0 / 12.0, .B: 5.0 / 12.0 ] let evenSpacingSpacerRatio: [Letter: CGFloat] = [ .C: 7.0 / 12.0, .D: 7.0 / 12.0, .E: 7.0 / 12.0, .F: 7.0 / 12.0, .G: 7.0 / 12.0, .A: 7.0 / 12.0, .B: 7.0 / 12.0 ] let evenSpacingRelativeBlackKeyWidth: CGFloat = 7.0 / 12.0 struct PitchRange: Identifiable { let range: ClosedRange<Int> let id: Int var lowerBound: Int { range.lowerBound } var upperBound: Int { range.upperBound } } struct ContentView: View { @State private var currentKeyboardId = 2 internal let ranges = [36...47, 48...59, 60...71, 72...83, 84...95, 96...107].enumerated().map { PitchRange(range: $0.element, id: $0.offset) } func noteOn(pitch: Pitch, point: CGPoint) { print("note on \(pitch)”) } func noteOff(pitch: Pitch) { print("note off \(pitch)”) } func noteOnWithVerticalVelocity(pitch: Pitch, point: CGPoint) { print("note on \(pitch), midiVelocity: \(Int(point.y * 127))”) } func noteOnWithReversedVerticalVelocity(pitch: Pitch, point: CGPoint) { print("note on \(pitch), midiVelocity: \(Int((1.0 - point.y) * 127))”) } var randomColors: [Color] = (0 ... 12).map { _ in Color(red: Double.random(in: 0 ... 1), green: Double.random(in: 0 ... 1), blue: Double.random(in: 0 ... 1), opacity: 1) } @State var lowNote = 24 @State var highNote = 48 @State var scaleIndex = Scale.allCases.firstIndex(of: .chromatic) ?? 0 { didSet { if scaleIndex >= Scale.allCases.count { scaleIndex = 0 } if scaleIndex < 0 { scaleIndex = Scale.allCases.count - 1 } scale = Scale.allCases[scaleIndex] } } @State var scale: Scale = .chromatic @State var root: NoteClass = .C @State var rootIndex = 0 @Environment(\.colorScheme) var colorScheme var body: some View { HStack { Keyboard(layout: .verticalIsomorphic(pitchRange: Pitch(48) ... Pitch(77))).frame(width: 100) VStack { HStack { Stepper("Lowest Note: \(Pitch(intValue: lowNote).note(in: .C).description)”, onIncrement: { if lowNote < 126, highNote > lowNote + 12 { lowNote += 1 } }, onDecrement: { if lowNote > 0 { lowNote -= 1 } }) Stepper("Highest Note: \(Pitch(intValue: highNote).note(in: .C).description)”, onIncrement: { if highNote < 126 { highNote += 1 } }, onDecrement: { if highNote > 1, highNote > lowNote + 12 { highNote -= 1 } }) } /// BUG DEMO BEGIN GeometryReader { geoProxy in ScrollViewReader { scrollProxy in ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 0) { ForEach(ranges) { range in Keyboard(layout: .piano(pitchRange: Pitch(intValue: range.lowerBound) ... Pitch(intValue: range.upperBound)), noteOn: noteOnWithVerticalVelocity(pitch:point:), noteOff: noteOff) .frame(minWidth: geoProxy.size.width * 0.5) .id(range.id) } } .frame(height: 200) .frame(maxWidth: .infinity) } .background(.black) .onChange(of: currentKeyboardId) { newValue in withAnimation { scrollProxy.scrollTo(newValue) } } .onAppear { scrollProxy.scrollTo(currentKeyboardId) } } } /// BUG DEMO END HStack { Stepper("Root: \(root.description)”, onIncrement: { let allSharpNotes = (0...11).map { Note(pitch: Pitch(intValue: $0)).noteClass } var index = allSharpNotes.firstIndex(of: root.canonicalNote.noteClass) ?? 0 index += 1 if index > 11 { index = 0} if index < 0 { index = 1} rootIndex = index root = allSharpNotes[index] }, onDecrement: { let allSharpNotes = (0...11).map { Note(pitch: Pitch(intValue: $0)).noteClass } var index = allSharpNotes.firstIndex(of: root.canonicalNote.noteClass) ?? 0 index -= 1 if index > 11 { index = 0} if index < 0 { index = 1} rootIndex = index root = allSharpNotes[index] }) Stepper("Scale: \(scale.description)”, onIncrement: { scaleIndex += 1 }, onDecrement: { scaleIndex -= 1 }) } Keyboard(layout: .isomorphic(pitchRange: Pitch(intValue: 12 + rootIndex) ... Pitch(intValue: 84 + rootIndex), root: root, scale: scale), noteOn: noteOnWithReversedVerticalVelocity(pitch:point:), noteOff: noteOff) .frame(minWidth: 100, minHeight: 100) Keyboard(layout: .guitar(), noteOn: noteOn, noteOff: noteOff) { pitch, isActivated in KeyboardKey(pitch: pitch, isActivated: isActivated, text: pitch.note(in: .F).description, pressedColor: Color(PitchColor.newtonian[Int(pitch.pitchClass)]), alignment: .center) } .frame(minWidth: 100, minHeight: 100) Keyboard(layout: .isomorphic(pitchRange: Pitch(48) ... Pitch(65))) { pitch, isActivated in KeyboardKey(pitch: pitch, isActivated: isActivated, text: pitch.note(in: .F).description, pressedColor: Color(PitchColor.newtonian[Int(pitch.pitchClass)])) } .frame(minWidth: 100, minHeight: 100) Keyboard(latching: true, noteOn: noteOn, noteOff: noteOff) { pitch, isActivated in if isActivated { ZStack { Rectangle().foregroundColor(.black) VStack { Spacer() Text(pitch.note(in: .C).description).font(.largeTitle) }.padding() } } else { Rectangle().foregroundColor(randomColors[Int(pitch.intValue) % 12]) } } .frame(minWidth: 100, minHeight: 100) } Keyboard( layout: .verticalPiano(pitchRange: Pitch(48) ... Pitch(77), initialSpacerRatio: evenSpacingInitialSpacerRatio, spacerRatio: evenSpacingSpacerRatio, relativeBlackKeyWidth: evenSpacingRelativeBlackKeyWidth) ).frame(width: 100) } .background(colorScheme == .dark ? Color.clear : Color(red: 0.9, green: 0.9, blue: 0.9)) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
