Hello friends of swift coding,
I try to create a contextMenu on TextEditor and TextField in SwiftUI for my macOS app.
TextEditor(text: $information)
.contextMenu{
Button {
print("gogogo")
} label: {
Text("Just do it!")
}
}
Code above is not working. What I try to achieve: in a TextEditor I like to right-click and either make changes to selected text or paste some textclippings to a certain position.
But the contextMenu inside an editor seems to be different to the contextMenu of other UI-Views.
How is it done, then? Or can I use the above code and have to put it somewhere else or give it a code word?
Related
Is it possible to have an inline TextField on tvOS?
For example, when clicking the "Name" button in Settings > About, you get presented directly with this screen:
But if one does
NavigationLink("Name") {
TextField("", text: $name)
}
Then you'll have to first focus and click on the TextField, and then you get the option to type in the content.
Is it possible to skip that step and go directly to the keyboard input?
Have a simple NavigationView with fixed content on both sides. The left pane just shows a couple of buttons and the right pane shows a graph using an NSView wrapped in an NSViewRepresentable. When viewing on iPad in portrait mode, the left pane disappears as expected but the 'back' button does not show. Can click in the area where the 'back' button was expected and the left pane shows up. There just isn't anything visible there.
What am I doing wrong?
var body: some View {
NavigationView {
VStack(alignment: .center) {
Text("This is the left side")
Button {
...
} label: {
Text("Create Estimate")
}.foregroundColor(Color.black)
Button {
...
} label: {
Text("Reset Results")
}.foregroundColor(Color.black)
Text("This is the end of the left side")
}
VStack {
Text("This is the right side")
AreaChartView(redrawCount: redrawCounter, scenario: activeScenario)
}
}
}
}
Update: This happens even when I comment out everything in the NavigationView above and replace with:
NavigationView {
Text("This is the left side")
Text("This is the right side")
}
Note that I created a new iOS project with nothing but this super-simple NavigationView and it shows the Back button just as expected. Since literally everything in my app's view except the NavigationView above is commented out, I'm wondering what else may be wrong in the environment. Note that my app is a multi-platform app rather than just iOS, though I don't know why that would matter.
OK - for any other poor soul who may encounter this...
When I found that even a trivial NavigationView had no 'Back' button (see question), it became clear that the trouble was not in the view code at all. Took some searching but discovered that somehow the default accent colors in the Assets file had been changed to white. This meant that the 'Back' button was white against a white background and was thus invisible.
Deleting these white accent colors causes SwiftUI to use defaults. Now the 'Back' button shows in blue as expected.
I'm building a macOS app with SwiftUI, and I'm trying to remove (or even cover up) the border added to a List item when I right-click it.
Here it is by default:
Now with a right-click and a contextMenu view modifier:
I figured this is an NSTableView quirk, so I tried the approaches in these three Stack Overflow posts:
Customize right click highlight on view-based NSTableView
NSTableView with menu, how to change the border color with right click?
Disabling the NSTableView row focus ring
NSTableView: blue outline on right-clicked rows
I couldn't get any of those to work, and that may be due to the fact that I can't subclass an NSTableView, but can only override its properties and methods with an extension. Here's what I have so far that successfully removes the default table background and such:
extension NSTableView{
open override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
//Remove default table styles
backgroundColor = NSColor.clear
enclosingScrollView!.drawsBackground = false
selectionHighlightStyle = .none
}
}
Is there any way to remove that right-click border in SwiftUI? I'm even open to covering it with other views, but I can't seem to draw SwiftUI views in that space around the table cell.
I found a workaround for this. I put my List in a ZStack and then set its opacity to zero. I then built out a fully custom version of the same list, but using LazyVStack:
//Message List
ZStack{
//Ghost list for keyboard control
List($model.messages, id: \.self, selection: $model.selectedMessages){ $message in
MessageItemView(message: $message)
}
.focusable()
.opacity(0)
//Custom UI for the above List
ScrollView{
ZStack{
LazyVStack(spacing: 5){
ForEach($model.messagesToday){ $message in
MessageItemView(message: $message)
}
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
Each list is bound to the same model, so if I click a message to select it in the custom UI, the same thing gets selected in the invisible List. All the keyboard shortcuts that come with table use in a List look like they are working on the custom version.
So how does this solve my original problem? You can right-click on the custom MessageItemView and the default ring around the cell is invisible, but the contextMenu still works (it's defined inside my MessageItemView).
This isn't as elegant as I'd like, but it's nice to have 100% control over the UI but still get all the keyboard controls that come for free with a List.
I have a textField in a SwiftUI file and want this fiel duo become the first responder and the keyboard should show up. In Swift I would simply do: textField.becomesFirstResponder().
Does anyone Has an idea how to do that in SwiftUI?
for a simpler solution, instead of writing a custom textfield you can use this library, https://github.com/siteline/SwiftUI-Introspect:
TextField("placeholder", text: $someText).introspectTextField { textField in textField.becomeFirstResponder() }
I'm trying to make navigation view that leads to destination view with scroll view, where navigation title of destination view would animate towards inline display mode or at least scroll behind the nav bar itself.
Basically I'm trying to replicate behavior of standard Music app, specifically when you go from Library to Songs.
There you have source view (Library) with its own title that is animated into inline display mode on scroll. When you tap Songs you also get list with new title (Songs) that also animates into inline display mode on scroll.
So I have main NavigationView with NavigationBarTitle. I move to destinationView with its own NavigationBarTitle and some long list of content. On scroll, NavigationBarTitle of main Navigation view changes to inline display mode, but NavigationBar of destination view behaves very odd: it's basically an overlay with no background and no animation.
And if you remove NavigationBarTitle of destination view all together it only makes things worse. It seems like it adds another transparent NavigationBar with nothing in it.
Also tried to add background to the navigation bar, looked around documentation, but found no solution.
Not sure if I'm doing something very wrong or it's just beta bug of SwiftUI or Xcode.
import UIKit
struct ContentView: View {
var body: some View {
NavigationView{
List(0..<20) { item in
NavigationLink(destination: DetailedView()) {
Text("Next view")
}
}
.navigationBarTitle("Source View")
}
}
}
struct DetailedView: View {
var body: some View {
List(0...25) { number in
Text("This is \(number)'th row")
}
.navigationBarTitle(Text("Destination View"))
// comment out line above to see empty frame of navigation bar
}
}
This is not a full answer to your question, but a temporary workaround: add top or vertical padding to your list on the child view, depending on your preference. This is what I have been doing until there is a better solution.
This will at least make the content scroll under the navigation header with a proper background rendered behind the header. It doesn't have the nice animation to make the title smaller.
struct DetailedView: View {
var body: some View {
List(0...25) { number in
Text("This is \(number)'th row")
}
.padding(.top)
.navigationBarTitle(Text("Destination View"))
}
}
This is fixed in the iOS 13.1 public release (with the App Store release of Xcode 11).
I'm currently on beta 5, and I think this is an ongoing bug with SwiftUI.
I noticed the same issue while doing the SwiftUI Landmarks Tutorials, and you can easily reproduce the issue: https://imgur.com/a/aYgUUH0
For now, to avoid seeing all the content scroll under a transparent navBar, I've converted all of my Navbars to display as inline, since automatic and large experience the issue.
List {
// ...
}
.navigationBarTitle(Text("MyTitle"), displayMode: .inline)