How can i change color of unselected icon (on screenshot) in TabView (SwiftUI)? Because this icon is invisible
You can use TabBarAccessor from my solution to Programmatically detect Tab Bar or TabView height in SwiftUI to change what you need as in below demo.
Tested with Xcode 11.4 / iOS 13.4
TabView {
Text("First View")
.background(TabBarAccessor { tabBar in
tabBar.unselectedItemTintColor = UIColor.red
})
.tabItem { Image(systemName: "1.circle") }
.tag(0)
Text("Second View")
.tabItem { Image(systemName: "2.circle") }
.tag(1)
}
Update: alternate via appearance also works
init() {
UITabBar.appearance().unselectedItemTintColor = UIColor.green
}
Related
I am trying to figure out how to use the functions from xcode with very limited information from the Apple documentation. How to use certain functions or variables or where to find examples and detailed explanations? The particular case that I am working on now is to offset the tab bar item images on the tab bar. I came across "itemPositioning", "stackedItemPositioning" but I have no clues about how to use them. Should I put it inside the initialiser function? And how to use it?
Also, a quick question. Is there any book or video covering like somethings that teach me how to explore unknown things on SwiftUI independently?
truct MainContentView: View {
#State private var navSelection = 0
init(){
UITabBar.appearance().backgroundColor = UIColor.clear
//stackedItemPositioning = UIOffset(horizontal: 0, vertical: -10)
}
var body: some View {
VStack(alignment: .center){
NavigationView{
TabView(selection: self.$navSelection){
Text("hey")
.tabItem{
Image(systemName: "heart.fill")
.offset(y:-15)
}
.tag(0)
Text("hey")
.tabItem{
Image(systemName: "magnifyingglass")
}
.tag(1)
Text("hey")
.tabItem{
Image(systemName: "capsule.portrait.fill")
}
.tag(2)
Text("hey")
.tabItem{
Image(systemName: "wand.and.stars")
}
.tag(3)
}
}
}
}
}
I am trying to make a menu with SwiftUI on iOS.
If the button that opens the menu is center-aligned, I wish the menu would be center-aligned as well. Regardless of the icon or texts used in the button. How to do it?
What is strange is that menu's alignment changes depending on the button's content. If I use one icon, it is center-aligned as expected. But if I use another icon, it is left-aligned.
Here is my code:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
VStack {
Text("Some text.")
}
VStack(alignment: .center) {
Spacer()
Menu {
Button(action: {}) {
Label("Menu item", systemImage: "star")
}
Button(action: {}) {
Label("Menu item", systemImage: "star")
}
} label: {
Image(systemName: "plus") // left-aligned menu
// Image(systemName: "line.horizontal.3") // center-aligned menu
.foregroundColor(Color.white)
.padding()
.background(Color.accentColor)
.clipShape(Rectangle())
}
}
}
.navigationTitle("Content")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
So far I have tried few things: adding .frame, embedding menu and button in HStacks and VStacks.
The only thing that center-aligned menu with plus button was this:
// other code
Menu {
Button(action: {}) {
Label("Menu item", systemImage: "star")
}
Button(action: {}) {
Label("Menu item", systemImage: "star")
}
} label: {
HStack {
Spacer()
.allowsHitTesting(false)
Image(systemName: "plus")
.foregroundColor(Color.white)
.padding()
.background(Color.accentColor)
.clipShape(Rectangle())
Spacer()
.allowsHitTesting(false)
}
}
// other code
After I have embedded label Image in HStack with Spacer() before and after - menu is centered. But... these Spacers are now clickable which I don't want. I was thinking that adding .allowsHitTesting(false) to Spacer() will disable taps on them, but it didn't.
Any other ideas? :)
EDIT:
I have just tested with "plus" button on few other simulators and menu has different alignment on different simulators (all with iOS 14.5):
left-aligned:
iPhone Xs
iPhone 11 Pro
iPhone 12 mini
center-aligned:
iPhone 8
iPhone 8 Plus
iPhone 11
iPhone 11 Pro Max
iPhone 12
iPhone 12 Pro
iPhone 12 Pro Max
iPhone SE 2nd generation
Is it a bug or is there some alignment option I am missing?
I want to remove the NavigationTitle Space without removing the back button.
I have already tried this:
.navigationBarItems(trailing:
NavigationLink(destination: Preferences(viewModel: viewModel).navigationBarHidden(true)) {
Image(systemName: "gear")
.font(.title2)
}
)
but that removes the back button as well.
Standard Back button cannot be shown without navigation bar, because it is navigation item, so part of navigation bar. I assume you just need transparent navigation bar.
Here is demo of possible solution (tested with Xcode 12.1 / iOS 14.1) / images are used for better visibility /
struct ContentView: View {
init() {
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithTransparentBackground()
UINavigationBar.appearance().standardAppearance = navBarAppearance
}
var body: some View {
NavigationView {
ZStack {
Image("large_image")
NavigationLink(destination: Image("large_image")) {
Text("Go to details ->")
}
}
.navigationBarItems(trailing: Button(action: {}) {
Image(systemName: "gear")
.font(.title2)
}
)
.navigationBarTitle("", displayMode: .inline)
}.accentColor(.red)
}
}
In my SwiftUI app, I would like to bring the navigation bar items down like in Apple's own UIKit apps.
Seen below is a screenshot from the Health app. Notice how the profile picture is in line with the 'Summary' text. This is what I am looking to achieve.
I have tried using .padding(.top, 90) but this has not worked as it does not bring down the virtual box that allows the button to be clicked. Using padding means that you have to tap the button above the image/text.
Thank you.
Unfortunately I didn't find any solution for changing navigation bar height in iOS 13 with SwiftUI, and had the same issues earlier. Solution below will fit you, if your navigation bar is always only black and you're ok with gap on the top:
struct NavBarCustomItems: View {
init() {
setNavigationBarToBlackOnly()
}
func setNavigationBarToBlackOnly() {
let blackAppearance = UINavigationBarAppearance()
blackAppearance.configureWithOpaqueBackground()
blackAppearance.backgroundColor = .black
blackAppearance.shadowColor = .clear // to avoid border line
UINavigationBar.appearance().standardAppearance = blackAppearance
UINavigationBar.appearance().scrollEdgeAppearance = blackAppearance
}
var body: some View {
NavigationView {
VStack {
NavigationBarMimicry()
// here is your content
HStack {
Text("Favorites")
Spacer()
Button(action: {}) { Text("Edit") }
}
.padding()
Spacer()
VStack {
Text("Main screen")
}
// you need spacer(s) to be sure, that NavigationBarMimicry is always on the top
Spacer()
}
}
}
}
// MARK: here is what you need in navigation bar
struct NavigationBarMimicry: View {
var body: some View {
HStack {
Text("Summary")
.bold()
.font(.system(size: 40))
.foregroundColor(.white)
.padding(.horizontal)
Spacer()
Rectangle()
.foregroundColor(.white)
.frame(width: 40)
.padding(.horizontal)
}
.background(Color.black)
.frame(height: 40)
.navigationBarTitle("", displayMode: .inline)
// you can add it to hide navigation bar, navigation will work via NavigationLink
// .navigationBarHidden(true)
}
}
struct NavBarCustomItems_Previews: PreviewProvider {
static var previews: some View {
NavBarCustomItems().environment(\.colorScheme, .dark)
}
}
the result should be like this:
P.S. maybe the other ways are:
Put views in this order: VStack { NavigationBarMimicry(); NavigationView {...}};
uncomment line of code: .navigationBarHidden(true);
I want to create a bottom bar which should be common for all my page. Here I am posting the image:
I know how to do it using storyboard. But how can I do it in SwiftUI?
This kind of view is called tab bar in iOS and in SwiftUI it is called TabView. It is declared like this:
var body: some View {
TabView {
Text("Favourites Screen")
.tabItem {
Image(systemName: "heart.fill")
Text("Favourites")
}
Text("Friends Screen")
.tabItem {
Image(systemName: "person.fill")
Text("Friends")
}
Text("Nearby Screen")
.tabItem {
Image(systemName: "mappin.circle.fill")
Text("Nearby")
}
}
}
Alternatively, you can use Label view for giving name & icon of the tab:
struct BottomTabBar: View {
var body: some View {
TabView{
Text("Profile Contents")
.tabItem{
Label("Profile",systemImage: "person.fill")
}
Text("Tv Contents")
.tabItem{
Label("Tv",systemImage: "tv.fill")
}
}
}
}