I'm trying to learn SwiftUI in an Xcode playground. I was trying to make a simple list (should be easy right?) but Xcode crashes the playground while it does work in an iOS project.
This is my code:
import UIKit
import PlaygroundSupport
import SwiftUI
struct ContentView: View {
var body: some View {
List(0..<5) { item in
Text("Test")
}
}
}
let viewController = UIHostingController(rootView: ContentView())
PlaygroundPage.current.liveView = viewController
Can't fix the issue but anyway you definitely should checkout swift playgrounds, they are great https://www.apple.com/swift/playgrounds/ :)
This might be a bug in Xcode 12.5, but everything works well in Xcode 13.0 Beta
Also, In SwfitUI, you can use PlaygroundPage.current.setLiveView instead of creating a hosting controller.
import SwiftUI
import PlaygroundSupport
struct ContentView: View {
var body: some View {
List(1..<5) {
Text("Item \($0)")
}
}
}
PlaygroundPage.current.setLiveView(ContentView())
This is what it looks like:
Related
There are a few similar questions here, but no answers resolve the issue for me.
My project doesn't start with a number.
It is essentially just this:
import Foundation
import UIKit
class DetailsView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setupBackgroud()
setupViews()
}
func setupBackgroud() {}
func setupViews() {}
}
#if DEBUG
import SwiftUI
#available(iOS 13, *)
struct DetailsViewPreview: PreviewProvider {
static var previews: some View {
// view controller using programmatic UI
DetailsView().showPreview()
}
}
#endif
and I get the error:
I have no idea what the 'mangled name' is.
The stupidest fix possible for this error.
I removed the compiler pre-proccessor statements.
Just remove #if DEBUG and #endif.
"It Just Works" 🤦♂️
Using the SwiftUI Xcode preview pane, I can click on the rendered views and see the code responsible for that view highlighted in the code pane (and vice versa). However, when I embed the view in a NavigationView or sometimes even addding a .navigationBarTitle() to the root view, I can't do that anymore. All views in the Navigation group just becomes one big view and the previewer can't identify the separate underlying pieces anymore.
Is this a bug? Is there a way to get around it? It's a really useful feature and most of my views sit in some kind of Navigation object.
Working
import SwiftUI
struct NavSample: View {
var body: some View {
Text("Hello, World!")
}
}
struct NavSample_Previews: PreviewProvider {
static var previews: some View {
NavSample()
}
}
Not Working
import SwiftUI
struct NavSample: View {
var body: some View {
NavigationView { // Adding this
Text("Hello, World!")
}
}
}
struct NavSample_Previews: PreviewProvider {
static var previews: some View {
NavSample()
}
}
The following trivial macOS app is written in SwiftUI 2.0.
import SwiftUI
#main
struct TempApp: App {
var body: some Scene {
WindowGroup { ContentView() }
}
}
struct ContentView: View {
var body: some View {
Text("Hello, beep!").padding()
}
}
When in the foreground, this app will emit an error beep on certain keystrokes (like "a"). What's the simplest way to suppress this beep?
An Xcode project illustrating this (and the answer) can be found here.
There are many older related questions on SO, but none of these are specifically about doing this in SwiftUI 2.0.
You can suppress the beep by adding a local monitor for the .keyDown event at the top level. This can be done simply in ContentView.init(), like so:
struct ContentView: View {
var body: some View {
Text("Hello, silence!").padding()
}
init() {
NSEvent.addLocalMonitorForEvents(matching: .keyDown) { _ in return nil }
}
}
This technique was inspired by this answer.
I'm trying to add a simple SwiftUI view to an existing project, but #State changes are not propagated properly. The code works as expected in a new project, but doesn't work in the older project. The same thing happens with #ObservedObject.
Code:
struct ChannelAccountsView: View {
#State private var showGreeting = true
var body: some View {
VStack {
Toggle(isOn: $showGreeting) {
Text("Show welcome message")
}.padding()
if showGreeting {
Text("Hello World!")
}
}
}
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
let contentView = ChannelAccountsView()
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
...
}
New project:
Old project:
Tried all of the obvious fixes:
Edited AppDelegate and added SceneDelegate
Edited Info.plist
Cleaned Project and the Derived data
Reset simulator data
Tested on multiple simulators/devices
Any idea what might be going on?
I had a similar issue and the root cause was that my target had the Reflection Metadata Level set to None under Swift Compiler - General category inside Build Settings.
Changing it to All fixed it for me:
Creating a new Target within the Project resolved the issues. Still not sure what the root cause is.
SwiftUI, macOS:
I'm trying to get a menu item to open "default PDF viewer of your choice", with a specific bundled PDF.
Here's what I have thus far:
import SwiftUI
import WebKit
import PDFKit
func Guide1(_ sender: Any) {
if let pdfURL = Bundle.main.url(forResource: "Guide1", withExtension: "pdf"){
if NSWorkspace.shared.open(pdfURL) {
}
}
}
func Guide2(_sender: Any) {
if let pdfURL = Bundle.main.url(forResource: "Guide2", withExtension: "pdf"){
if NSWorkspace.shared.open(pdfURL) {
}
}
}
Now, what I'm missing is how to call these functions.
From previous tutorials, I've found that one way of getting the menu items to "do something" is to ctrl-click and drag the Menu Item entry to First Responder, and then select functions from the list. However, these Guide1 + Guide2 functions are not displayed.
Other tutorials suggest using #IBAction - but the minute I type that into a SwiftUI app, an error tells me to get the #IBaction replaced with "nothing". So I cannot use those either.
So, are these even valid strings for opening a PDF - and if so, how do I connect a dropdown menu item so that these PDFs are opened?
It needs to be added not in SwiftUI view but, for example and simplest, in AppDelegate as below
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBAction func Guide1(_ sender: Any) {
if let pdfURL = Bundle.main.url(forResource: "Guide1", withExtension: "pdf"){
if NSWorkspace.shared.open(pdfURL) {
}
}
}
then in your Main.storyboard (or XIB) just CTRL-drag from menu item to FirstResponder and Guide1 action is there to bind (sometime build might be required before that, but as tested on Xcode 11.2 it just works).