The look of my tab view is great. Everything in fact looks good. But with the current code. The ScrollView ends behind the tab bar instead of above. I'm guessing it has to do with it being a ZStack (it - meaning the content).
I tried adding padding on each view inside the switch (padding bottom same height as tab bar but not working).
The two results I've gotten is either it won't scroll enough to see all content but tab bar looks good.
OR
Scrolling works great but the tab bar has some overlaying issues visually with showing whitespace.
I just don't know how to move around the code any more to get a better result. :(
//Landing-page..
VStack {
ZStack(alignment: Alignment(horizontal: .center, vertical: .bottom)) {
switch tabController.selectedIndex {
case 0:
HomeView()
.padding(.bottom, 50)
case 1:
Text("Test..")
case 2:
Text("Test...")
case 3:
Text("Test....")
default:
VStack {
Text("Default View")
}
}
CustomTabView()
}
}
.background(Color.gray.ignoresSafeArea()).edgesIgnoringSafeArea(.bottom)
// TabView..
HStack {
// tabControllers.icons.count = 4 tabs at the moment
ForEach(0..<tabController.icons.count, id: \.self) { tab in
Button(action: {
// animation when changing tab comes here eventually
tabController.selectedIndex = tab
}, label: {
Spacer()
Image(systemName: tabController.icons[tab])
.frame(width: 50, height: 50)
.font(.system(
size: 22,
weight: tabController.selectedIndex == tab ? .semibold : .regular,
design: .default))
.foregroundColor(tabController.selectedIndex == tab ? Color.themeAccent : Color.themeAccent.opacity(0.3))
.background(tabController.selectedIndex == tab ? Color.primaryPurple : nil)
.cornerRadius(tabController.selectedIndex == tab ? 30 : 0)
Spacer()
})
}
}
.padding()
.background(Color.blue)
.clipShape(CShape())
.shadow(color: Color.black.opacity(0.3), radius: 20, x: 0.0, y: 0.0)
The ScrollView starts at the top in the HomeView.
Tab view showing correctly, but not scrollview
ScrollView showing correctly, but not tab view
I think you can get rid of the ZStack, put the switch/case in the VStack and the CustomTabView() below that. The ScrollView will push the CustomTabView to the bottom and not overlap it. If not all of the views in the switch are ScrollViews, then you can add a Spacer() above the CustomTabView, which will push the views apart to the top and bottom.
Related
I created SwiftUI Button and its touch area is slightly strange. The touch area extends the label of the button.
This is my code.
struct TestView: View {
var body: some View {
HStack(spacing: 0) {
Spacer()
Button {
print("aaaaaa")
} label: {
HStack(spacing: 0) {
Spacer()
}
.frame(width: 50.0, height: 50.0)
.background(Color.yellow)
}
Spacer()
}
.frame(height: 50.0)
.background(Color.red)
}
}
And I'll attach the result in simulator.
The button area is filled with yellow color. But I could click the button outside of yellow color.
The same thing happens in real device too.
How is this possible?
This is a completely normal behavior of Button/onTapGesture in SwiftUI. Its touch area is slightly bigger than its border size.
This is not a bug or glitch.
No matter what I've tried I cannot get this navigation bar item to align with the large title on this View? I have tried padding or placing it in a VStack with a Spacer() but neither push it down. How can I properly align it?
var body: some View {
NavigationView {
//omitted
.navigationTitle("Exertion")
}
.navigationBarItems(
trailing:
Button(action: {
self.isShowingExertionCalendarSheet.toggle()
}) {
Image(systemName: "calendar")
.font(.system(size: 30, weight: .bold))
}
)
}
}
You can't. Because the Navigation Title is dynamic as it can change from small to big on scroll, at least you say otherwise, the UI does not allow you to set up the navigation items aligned vertically in other position other than the expected. That is right below the safe area. Is like giving a leading navigation item hides the back button. This is how Cocoa Touch either via SwiftUI or UIKIt works.
Well I think that you can do something like this:
.navigationBarItems(
leading: Text("Exertion")
.fontWeight(.bold)
.font(.largeTitle),
trailing: Button(action: {
... your code here ...
}, label: {
Image(systemName: "calendar")
.foregroundColor(Color("Some Blue"))
})
)
I'm reusing one view for different scenarios. One is as modal window and second one is also modal but within navigation view.
My problem is that I can switching between options in picker only if view is as modal and not navigation view. If is within navigation view i'm not able to click on any option presented in picker.
ZStack {
Color("my-orange").edgesIgnoringSafeArea(.top)
VStack(alignment: .leading) {
if !self.picture {
Image("van")
.resizable()
.frame(width: UIScreen.main.bounds.width, height: 275)
.padding(.leading)
}
Picker(selection: $langauge, label: Text("Test")) {
ForEach(0..<contentLanguages.languages.count, id:\.self) { index in
Group {
if self.contentLanguages.languages[index].isOn {
Text(self.contentLanguages.languages[index].country).tag(index)
.foregroundColor(.white)
}
}
}
}.pickerStyle(SegmentedPickerStyle())
.padding([.leading, .trailing], 60)
.padding([.top, .bottom])
.background(Color("my-orange"))
Spacer()
TabBar(index: $index)
.offset(y: self.picture ? -30 : 0)
}.edgesIgnoringSafeArea(.all)
}
This is how the view looks where I'm not able to switch between options
And here I can switch within same view but not opened as navigation view
Update:
What I found out there is problem with .edgeIgorningSafeArea. When I removed this part of the code i'm able to switch on both scenarios but i want to keep switcher always on the top.
I have figure out by moving picker to the view where is NavigationView -> NavigationLink.navigationBarItems
And origin picker is under if statement and shows when is needed.
My question now is: if i have picker as navigationBarItems how I can handle events on that view?
Im working in swift ui. I want to put a button on the side of the NavigationBar title.
I want to be able to click the user image and navigate to another view
Can this be done?
The buttons are placed in navigation bar using .navigationBarItems(). Any view can be used inside a Button, so a button almost like the one in your image can be declared like this:
var body: some View {
NavigationView {
// the rest of your UI components
.navigationBarTitle("Browse")
.navigationBarItems(trailing: Button(action: {}) {
VStack {
Spacer()
Image("name")
.resizable()
.frame(width: 45, height: 45)
.clipShape(Circle())
}
})
}
}
Please note that it has a slightly different alignment (is going to get drawn a bit higher than your example).
This should solve the problem with the offset, but it is very hacky. And maybe there is a better answer to your problem than this. But if you are ok with this answer please give LuLuGaGa an upvote as I have copied a lot from him. And I did not come up with that answer myself, but I can not remember where I found the original answer.
NavigationView {
// the rest of your UI components
.navigationBarTitle("") // To hide the real navigationBarTitle
.navigationBarItems(leading:
Text("Browse").font(.largeTitle).bold().padding(.top, 10), // To add a fake navigationBarTitle
trailing: Button(action: {}) {
VStack {
Spacer()
Image("swiftui")
.resizable()
.frame(width: 45, height: 45)
.clipShape(Circle())
}
} .buttonStyle(PlainButtonStyle()) // You should also add that to your code otherwise the picture will turn blue
)
}
var body: some View {
NavigationView {
Text("SwiftUI")
.navigationBarTitle("Welcome")
.navigationBarItems(trailing:
Button("Bar button") {
print("Bar button!")
}
)
}
Try this
NavigationView{
.navigationBarTitle("Browse")
.navigationBarItems(trailing:
Button(action: { // Move to next View }){
Image()
}
)
}
I would like to add a plus button to the navigation bar items using the system plus image in SwiftUI. However, I am unable to prevent the system image from scaling dynamically when the accessibility font changes.
How can I stop it resizing so it acts like a standard UINavigationBarButtonItem system plus button?
The accessibility feature of holding on to a navigation bar button for large font types also doesn't work like it does with UIKit.
Really frustrating that a potentially simple thing can't be done with SwiftUI and that accessibility hasn't been thought about. The SwiftUI tutorials profile bar button also doesn't work for large font sizes. (PS SwiftUI is the future)
Here was my attempt:
struct ContentView : View {
var body: some View {
NavigationView {
List {
Text("Stop + Bar Button resizing")
.lineLimit(nil)
}
.navigationBarTitle(Text("Plus"))
.navigationBarItems(trailing:
PlusNavigationButton()
)
}
}
}
struct PlusNavigationButton: View {
var body: some View {
PresentationButton(
Image(systemName: "plus")
.resizable()
.frame(width: 44, height: 44),
destination: NewView())
}
}
You should build what you exactly want. So if you want to use 16x16 image with some extra hitTest area, you can build like this:
var body: some View {
PresentationButton(
HStack() {
Spacer()
Image(systemName: "plus")
.resizable()
.frame(width: 16, height: 16)
Spacer()
}.frame(width: 44, height: 44),
destination: NewView()
)
}
or if you like some space around your image and let it fill the rest, you can:
var body: some View {
PresentationButton(
Image(systemName: "plus")
.resizable()
.padding(14)
.frame(width: 44, height: 44),
destination: NewView()
)
}