I'm building my first SwiftUI app. For some reason when I command+click on an HStack the "Extract Subview" and other options don't show up. Any reason why I'm not seeing these options? I'm using Core Data and UITableView.appearance to remove lines in my List as well. Does it have to do with using core data and my use of UITableView? Couldn't find any answers after researching. Appreciate the help.
Not sure if this is an Xcode issue/bug but as of Xcode 11.4 the "Extract Subview" option (and others) show up only if the Canvas is being shown.
So, enable live preview and then cmd-click on the View you want to extract.
I got the same problem. You should do command + right click.
I was having the same problem but could not solve it with the presented solution. Came to realize that you need to have an Object embedded in another to be able to extract it.
In the example below, I would not be able to extract the HStack, but it will show up in the VStack.
struct ContentView: View {
var body: some View {
HStack(){
Image("sal")
.resizable()
.frame(width: 100, height: 100)
.aspectRatio(contentMode: .fit)
.cornerRadius(20)
.padding(.trailing)
VStack(alignment: .trailing){
Text("Camino La Angostura")
Text("2.5 Km.")
}
}
}
}
Related
I select the systemImage "map" and "person" for the tabItem, but the images are in filled format which must be in hollow format. What's the reason?
struct TestView: View {
var body: some View {
TabView {
Text("Map!")
.tabItem {
Label("Map", systemImage: "map")
}
Text("Profile")
.tabItem {
Label("Person", systemImage: "person")
}
}
}
}
Xcode: 13.1
SF Symbols: 3.1
This is standard SwiftUI behaviour in iOS 15, as it implements by default the recommendations from Apple’s Human Interface Guidelines, which says tab bars should use filled variants of SF Symbols, while sidebars on iPad should use the outline variant.
The effect is achieved by iOS automatically applying the .symbolVariants environment value, as noted in the symbol variants documentation:
SwiftUI sets a variant for you in some environments. For example, SwiftUI automatically applies the fill symbol variant for items that appear in the content closure of the swipeActions(edge:allowsFullSwipe:content:) method, or as the tab bar items of a TabView.
If you absolutely want to get rid of the fill mode, it’s deliberately made tricky but not impossible. You have to override the supplied \.symbolVariants environment variable directly on the Label element, inside your tabItem declaration:
Text("Map!")
.tabItem {
Label("Map", systemImage: "map")
.environment(\.symbolVariants, .none)
}
Using the .symbolVariants(.none) modifier, or trying to set the environment value higher up the view graph, won’t work.
Now that you see how to override the effect, I would still advise using the filled forms in the tab bar. Given that the tab bar no longer has a background colour difference from the rest of the page in many cases, the extra visual weight given to tab items by use of the filled variant lends the right amount of visual weight to those elements.
I select the systemImage "map" and "person" for the tabItem, but the images are in filled format which must be in hollow format. What's the reason?
struct TestView: View {
var body: some View {
TabView {
Text("Map!")
.tabItem {
Label("Map", systemImage: "map")
}
Text("Profile")
.tabItem {
Label("Person", systemImage: "person")
}
}
}
}
Xcode: 13.1
SF Symbols: 3.1
This is standard SwiftUI behaviour in iOS 15, as it implements by default the recommendations from Apple’s Human Interface Guidelines, which says tab bars should use filled variants of SF Symbols, while sidebars on iPad should use the outline variant.
The effect is achieved by iOS automatically applying the .symbolVariants environment value, as noted in the symbol variants documentation:
SwiftUI sets a variant for you in some environments. For example, SwiftUI automatically applies the fill symbol variant for items that appear in the content closure of the swipeActions(edge:allowsFullSwipe:content:) method, or as the tab bar items of a TabView.
If you absolutely want to get rid of the fill mode, it’s deliberately made tricky but not impossible. You have to override the supplied \.symbolVariants environment variable directly on the Label element, inside your tabItem declaration:
Text("Map!")
.tabItem {
Label("Map", systemImage: "map")
.environment(\.symbolVariants, .none)
}
Using the .symbolVariants(.none) modifier, or trying to set the environment value higher up the view graph, won’t work.
Now that you see how to override the effect, I would still advise using the filled forms in the tab bar. Given that the tab bar no longer has a background colour difference from the rest of the page in many cases, the extra visual weight given to tab items by use of the filled variant lends the right amount of visual weight to those elements.
I just create a swiftUI project and type this code on CntentView.swift. But the result is this image below. It was the same when I tried to run it on a real machine.
Why?
Environment:
Xcode Version 12.2(12B45b),
This is code of "Test13App.swift". Not edited any line.
Thank you very much for your comments. Since I only have iPad pro (and not have iPhone), I just knew this is a default behaviour of iPad split view now by your comments. Adding .navigationViewStyle(DefaultNavigationViewStyle()) right after NavigationView solved the problem like this
SwiftUI NavigationView on the iPad Pro
Sorry and Thanks very much!
If you want to change the style of your NavigationView on iPad making it similar to iPhone, you could use the:
.navigationViewStyle(StackNavigationViewStyle())
option in your NavigationView.
Like this:
struct ContentView: View {
var body: some View {
NavigationView{
Text("prova")
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
When focused on both iPhone and iPad devices some developer's missing set the navigationview style type.
Set the NavigationView Style
I have a list in iOS 14 / Xcode 12
Im using the following/tried the following to hide the little arrows in the corner:
.listRowInsets(EdgeInsets())
.background(Color.white)
.listStyle(PlainListStyle())][1]][1]
the easiest way to remove the arrow i think is to get the NavigationLink out of the List and use the tag or isActive initialiser of NavigationLink to define whether or not the link should be activated
Hey! You need to hide the navigation link. Try This Code Below...
NavigationLink(destination: DetailView(item: yourItem)) { //Your Nav Link
EmptyView()
}.frame(width:0).opacity(0) //Hide Your Link Programmatically
I have an app that loads a tabbar with a view as initial screen, RecipeList(). Inside of RecipeList I call another view to show a recipe full screen. In RecipeList file I have code to show or hide the status bar checking if the recipe detail fullscreen view is loaded or not. It works perfectly if I preview it in xcode, BUT when I preview the code below, which is my Home() view file, and what I want to load as initial screen due to tabbar need, THEN the code inside of RecipeList to show or hide statusbar doesnt work anymore, and status bar is always on.
If i try to hide the statusbar in the code below, it works, but then is always off, something i dont want. Only wanna hide it for the fullscreen view.
I actually used this Introspect package from Github to hide the tabbar when the child view is loaded full screen, and i made it work!
SwiftUI hide TabBar in subview
https://github.com/siteline/SwiftUI-Introspect
Actually, I wonder if anyone has used Introspect to hide the statusbar like the tabbar. I tried to use it, but I am a rockie, I only know a bit of SwiftUI, no Swift, no view controller experience, nothing.
But I have a totally functional app with only this issue, and I am super frustrated not to have the skills to know why the tabbar view is forcing a persistent status bar.
Any help, please?
var body: some View {
ZStack {
Color("background2")
.edgesIgnoringSafeArea(.all)
TabView {
RecipeList().tabItem {
Image(systemName: "book.fill")
.font(.system(size: 24, weight: .bold))
Text("Galería")
}
PostList(section: sectionData[0]).tabItem {
Image(systemName: "list.bullet")
.font(.system(size: 22, weight: .bold))
Text("Listado")
}
}
.accentColor(Color("accent"))
.introspectTabBarController { tabBarController in
// customize here the UITabBarViewController if you like
self.viewModel.tabBarController = tabBarController
}
}
}
I can suggest you using the #EnvironmentObject wrapper which basically allows you to use an object as global state. You can find fair amount of tutorials explaining how to do that and inject it in your initial view so that this object is accessible in the whole view hierarchy.
Once you have that global state set up, you can hide your status bar conditionally like this:
MyOutterWrapper {
Text("Some text")
}
.statusBar(hidden: myGlobalState.statusBarHidden)
If you are using NavigationView note that hiding the status bar works best if you set it up there (also assuming navigation view is your first view that appears).
Now all you got to do is inside your view set the variable to true when entering full screen and set it back to false when exiting. Hope that helps!
EDIT: Forgot to mention that hiding status bar as of June 26, 2020 only works if it's set on the initial view. You cannot change it later and that's the reason we set up this variable in order to go back and change the value dynamically.