Hello heroes of the internet,
When we develop apps on Xcode we can preview apps on the Canvas, and it looks something like this:
Luckily, SwiftUI allows for splitting up the code in an easy manner, with "Views". Say you have a simple view and you want to preview it on a blank canvas, not on the phone with the phone's aspect ratio and notch and all that. I want to display my view in a simple blank canvas, like in the image below.
How can I do such thing?
Change to the selectable preview mode at the bottom of the canvas:
Then add this to the preview code:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.previewLayout(.sizeThatFits) // here
}
}
Firstly, set up your preview layout in a fixed frame like below:
struct FContentView_Previews: PreviewProvider { //don't forget to change name
static var previews: some View { //don't forget to change name
FContentView()
.previewLayout(.fixed(width: 480, height: 320)) //this line of code
}
}
Then, set the preview option to Selectable like the below image.
You can also refer to my latest updated answer: fixed frame preview in canvas
Related
Let's say my application has two pages; Login Page and Main Page. I created these two with SwiftUI View separately. How will I make the transition between them. I tried NavigationView but the second page opens with a NavigationBar (with the First Page named arrow). In summary, how can I switch between two views cleanly?
you can do this simply with switch or if/else :)
class Wnd : View {
#State var firstShown: Bool
var body: some View {
if firstShown {
FirstView(firstShown: $firstShown)
}
else
{
SecondView(firstShown: $firstShown)
}
}
}
firstView and secondView have Binding to firstShown var
Another one solution is to use handlesExternalEvents for switching views.
sample of usage: https://stackoverflow.com/a/65415593/4423545
Another solution is to hide NavigationBar:
.navigationBarHidden(true)
Writing a Macos app. The following code just puts up a simple navigation list. Everything is fine with single clicking the Row links and displaying the Detail row.
If you double click the NavigationLink, another window opens with only the Text view on it. During my testing, there was a button to dismiss the view on the detail window, and if clicked, the original window would close leaving this stripped down view open.
I have to assume that no one else is seeing this since I cannot see anything from other people.
Does anyone have any ideas what would cause this to happen?
import SwiftUI
struct ContentView: View {
var body: some View {
HStack {
NavigationView {
List(0..<100) { row in
NavigationLink(destination: Text("Detail \(row)")) {
Text("Row \(row)")
}
}
}
}
}
}
Just use sidebar list style explicitly
List(0..<100) { row in
// ... content here
}
.listStyle(SidebarListStyle()) // << here !1
Tested with Xcode 13.2 / macOS 12.1
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello")
Text("World")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
The code above results in two preview windows: one with text "Hello", second window holds "World"
Every time I add something like Text() or whatever, it appears in the second preview window. Adding more elements automatically leads to new preview windows. THe code in the PreviewProvider remains the same, so it's not duplicate previews, it just the separate previews for EACH element...
I tried to restart Xcode, change simulator devices, create new projects - nothing changes.
It started after I added duplicate preview in one project and then deleted it by removing appropriate lines in the PreviewProvider. After that all new projects or all new files in old projects show this strange behaviour.
The body by default is a #ViewBuilder in SwiftUI 2.0, so it just generate a group of views inline, thus having two Text element you got two previews. If you want just one Preview your body should have the one top view, like
struct ContentView: View {
var body: some View {
HStack {
Text("Hello")
Text("World")
}
}
}
You have to put the two Text elements into a Container, like e.g. a VStack.
I am trying to preview some View by using Widget context, like:
struct MyTasksView_Previews: PreviewProvider {
static var previews: some View {
MyTasksView(
myTasks: Fake.myTasks,
user: Fake.user,
error: ""
)
.previewContext(WidgetPreviewContext(family: .systemMedium))
}
}
However, I'm getting this error while attempt to run the preview. And, I'm not sure why it is happing.
RemoteHumanReadableError: Unknown preview provider “MyTasksView_Previews”
MyApp does not contain a preview provider named “MyTasksView_Previews”. Check your build settings to ensure the preview provider is compiled into your product.
I, also, tried to use a simple Text(text).previewContext(WidgetPreviewContext(family: .systemMedium)), but it did not work either. I'm using the Xcode beta 5.
In Apple Emoji Rangers Demo App for WWDC 2020. We can see this piece of code for preview:
struct CharacterNameView_Previews: PreviewProvider {
static var previews: some View {
CharacterNameView(CharacterDetail.panda)
.previewContext(WidgetPreviewContext(family: .systemSmall))
}
}
I had the similar issue and I solved it by putting the View inside a VStack (or another container).
Here is my code that worked:
struct WidgetViewPreviews: PreviewProvider {
static var previews: some View {
VStack {
WidgetView(entry: .mock)
}
.previewContext(WidgetPreviewContext(family: .systemSmall))
}
}
It's a bug in Xcode, you can only use previewContext of "single" Widgets Target.
So you need to unselect other Targets.
I had the same problem when adding widgets extension to my UIKit app.
Changing the Class target membership to widget extension solved this for me.
Add Widget extension target, and activate it. For more information
https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension
I have added an image (jpg) from my Photo Album to the UserResources folder (via the + menu in the upper right of the Playground app). How do I reference that file when declaring a SwiftUI Image?
I have tried using the entire path:
let path: String = { Bundle.main.paths(forResourcesOfType: "JPG", inDirectory: nil)[0] }()
It seems to give me the path to the desired file, “PICT0024.JPG”:
/var/mobile/Containers/Data/PluginKitPlugin/F01FA67E-97CA-4590-915A-C8071507C6E0/Library/Application Support/Main Module Resources Bundles/55929C8C-46C9-4691-B86B-389D1473E9A8.bundle/Contents/Resources/PICT0024.JPG
I then declare:
Image(systemName: path)
But the image is not shown. I probably have the wrong reference, but cannot figure out what I need to specify.
Oh, just this
Image(“PICT0024.JPG”)
doesn’t work either.
What is the proper way to reference that image file?
Please confine answers to SwiftUI 5 and editing on an iPad. Using XCode at the moment isn’t an option.
Thanks.
Image(systemName: path)
this constructor one is for system SF Symbols
Image(“PICT0024.JPG”)
this constructor is for images in Assets catalog
The external images you have to use like this
Image(uiImage: UIImage(contentsOfFile: path))
import SwiftUI
import PlaygroundSupport
// Add image to the project with the "+" button,
// then select either the file, or image icon,
// then navigate to desired image,
// then add it to the iPad Playground project
let imageFileNameString = "IMG_2702.jpeg"
struct ContentView: View {
var body: some View {
// the method below requires the UIImage be unwrapped
Image(uiImage: UIImage(named: imageFileNameString)!)
// -or-
// The commented-out method below does not require any unwrapping.
// Typos will fail with "something went wrong around here" error
// Image(uiImage: UIImage(imageLiteralResourceName: imageFileNameString))
.resizable()
}
}
PlaygroundPage.current.setLiveView( ContentView() )
This is what I used:
https://www.appcoda.com/swiftui-swift-playgrounds-ipad-mac/
[Edit by original poster]
Summarizing from the article (worth a read because it discusses far more than how to access an image resource), here’s how to do it:
Type Image. and using the autocomplete bar, pick the moon and mountains icon (ImageLiteral)
That displays the “Images” popup. If you have not already added an image, choose either “Insert From...“, “Photo Library”, or “Take Photo”. Once you add an image, select it and press, “Use” (upper right corner of popover).
The result looks like this:
[The image here is of buttercups, Ranunculus acris.]