How to remove opacity animation in SwiftUI NavigationLink - swiftui

When tapping on a NavigationLink, it reduces the opacity slightly. Is there a way to disable this. I tried using .buttonStyle(PlainButtonStyle()) but that didn't have the desired effect.
It is embedded in a scrollView (preferred over List for customizability):
ScrollView {
ForEach(items){ item in
NavigationLink(destination: DetailView()){
HStack{
Text("title")
Spacer()
Image(systemName: "chevron.right")
}
.padding()
.background(
RoundedRectangle(cornerRadius: 10, style: continuous)
.foregroundColor(Color.gray)
)
}
}
}

Here is possible solution. Tested with Xcode 11.4 / iOS 13.4
Use custom button style that just returns label view (w/o highlight effect)
struct FlatLinkStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
}
}
and
NavigationLink(destination: DetailView()){
HStack{
Text("title")
Spacer()
Image(systemName: "chevron.right")
}
.padding()
}.buttonStyle(FlatLinkStyle()) // << here !!

Related

How to center a text in the second row with respect to an image in the row below in SwiftUI?

In the screenshot below, the purple image is not aligned horizontally with the globe symbol. I'm trying to center the navigation title with respect to the logo above it which I can totally do with a VStack. However I don't know how to align the logo itself with the navigation trailing item (globe in the screenshot). Any tips? ideas? tutorials? thank you!
struct ContentView: View {
var body: some View {
NavigationView {
Text("Hello")
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button {} label: {Image(systemName: "globe")}
}
ToolbarItemGroup(placement: .principal) {
VStack {
Image("image")
.resizable()
.frame(width: 64.0, height: 24.0)
Text("Navigation Title")
}
}
}
}
.navigationBarTitleDisplayMode(.inline)
}
}
Just do same for leading toolbar item (because items are independent and one alignment does not affect other - only size of bar)
Tested with Xcode 13.4 / iOS 15.5
*borders are for better visibility
Text("Hello")
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
VStack(alignment: .leading) {
Button {} label: {Image(systemName: "globe")}
.frame(height: 24.0)
Text("X").foregroundColor(.clear)
}.border(.red)
}
ToolbarItemGroup(placement: .principal) {
VStack {
Image("picture")
.resizable()
.frame(width: 64.0, height: 24.0)
Text("Navigation Title")
}.border(.green)
}
}

Toolbar disappears when StackNavigationViewStyle on iPad | SwiftUI iOS 15

I have this TabView:
ZStack(alignment: Alignment(horizontal: .center, vertical: .bottom)){
TabView(selection: $mainViewProperties.currentView) {
...
//HOME
NavigationView{
HomeView(
)
.navigationBarTitleDisplayMode(.inline)
}
.tag(MainViewProperties.Views.HOME)
...
}
//My Custom NavBar
CustomBottomNav(selectedTab: $mainViewProperties.currentView)
.padding()
}
And the HomeView's body is this:
List{
ForEach((0...30), id: \.self){ i in
HStack{
Spacer()
Text("New \(i)")
Spacer()
}
.padding()
.background(Color.backgroundOver)
.cornerRadius(.lotoUpCornerRadius)
.lotoUpShadow() // <- CUSTOM EXTENSION
//Bottom padding
if i == 30 {
VStack{
}
.frame(height: .paddingForBottomNav) // <- CUSTOM EXTENSION
}
}
.listRowSeparator(.hidden)
.listRowBackground(Color.background)
}
.listStyle(PlainListStyle())
.background(
Color.background
)
.toolbar {
ToolbarItem(placement: .principal){
Text(String.R.home_title)
.font(getLotoUpFont(size: 20))
.bold()
.foregroundWithPrimaryGradient() // <- CUSTOM EXTENSION
}
}
That look like this:
I don't want the side bar navigation on the iPad, so I added StackNavigationViewStyle to the NavigationView like this:
//HOME
NavigationView{
HomeView(
)
.navigationBarTitleDisplayMode(.inline)
}
.navigationViewStyle(.stack) //<- HERE
.tag(MainViewProperties.Views.HOME)
But then the Toolbar's background was not displayed anymore:
How can I get the Stack Navigation and the Toolbar's background get along together?
PD: I also tried this on HomeView:
.toolbar {
ToolbarItem(placement: .principal){
HStack{
Spacer()
Text(String.R.home_title)
.font(getLotoUpFont(size: 20))
.bold()
.foregroundWithPrimaryGradient()
Spacer()
}
.background(
Color.red
.frame(maxWidth: .infinity, maxHeight: .infinity)
.edgesIgnoringSafeArea(.all)
)
}
}
But it lets spaces that I don't want:
EDIT:
I tested this on a real device (iPhone 8 Plus) and worked fine, the NavigationBar was there, but on the simulated iPhone 8 plus the NavigationBar background was translucent.
So now I'm suspecting on the simulator. I don't have an iPad to test this out though.
It seems to be a bug on simulator with iOS 15. On iOS 15.2 it works just fine.

How to position text and a button in this manner?

This is an example of what I am trying to do.Link to image of design to implement. I am unsure how to position a button and text at the top of the screen in this manner coding in swiftui. Alternatively I thought I could use the navigation bar inline and customise that but I am unsure.
var body: some View {
VStack (alignment: .trailing) {
HStack(spacing:10) {
Button(action: {
}) {
Image(systemName: "line.horizontal.3")
.font(.headline)
}
Text("WeCollab")
.foregroundColor(.white)
.font(.title)
//padding(.leading,40)
Spacer()
}
.padding(.top,UIApplication.shared.windows.first?.safeAreaInsets.top)
.background(customPurpleColour)
Spacer()
}
.edgesIgnoringSafeArea(.top)
}
}
Seems like you're on the right track. In order to keep the title centered, it seemed easier to make a ZStack. The menu button gets it's own .leading-aligned VStack and then the title goes on top of that.
The edgesIgnoringSafeArea and padding can be simplified so that you don't have to use the screen size safe areas.
struct ContentView: View {
var body: some View {
VStack {
ZStack {
VStack {
Button(action: { }) {
Image(systemName: "line.horizontal.3")
.font(.headline)
}.padding(.leading)
}.frame(maxWidth: .infinity, alignment: .leading)
Text("WeCollab")
.foregroundColor(.white)
.font(.title)
}
.background(Color.purple.edgesIgnoringSafeArea(.top))
Spacer() //other content goes here
}
}
}

Is it possible to replace the default back button and sidebar icon in iPad's Navigation Bar using NavigationView in SwiftUI?

I'm trying to make an iOS app that uses SwiftUI's NavigationView to build a side menu.
On iPhone it works perfectly, but on iPad I cannot get Rid of the Sidebar button and the back button text and icon. I would like to replace those buttons with the three horizontal lines icon named line.horizontal.3
Landscape screenshot with side menu icon I'd like to replace with three lines icon
Portrait screenshot with back button (woth icon and text) I'd like to replace with three lines icon
The code I'm using is the following:
import SwiftUI
struct ContentView_iPad: View {
#State var showMenu: Bool = false
var body: some View {
NavigationView{
MenuView()
iPad_menu()
.navigationBarTitle("Side Menu", displayMode: .inline)
.navigationBarItems(leading:
(Button(action: {
withAnimation{
self.showMenu.toggle()
}
}){
Image(systemName: "line.horizontal.3").imageScale(.large)
}
))
.navigationViewStyle(StackNavigationViewStyle())
}
}
}
The MainView:
import SwiftUI
struct iPad_menu: View {
var body: some View {
EmptyView()
.background(Color.black)
}
}
The MenuView:
import SwiftUI
struct MenuView: View {
var body: some View {
VStack(alignment: .leading) {
HStack {
Image(systemName: "person")
.foregroundColor(.gray)
.imageScale(.large)
Text("Profile")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 100)
HStack {
Image(systemName: "envelope")
.foregroundColor(.gray)
.imageScale(.large)
Text("Messages")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
HStack {
Image(systemName: "gear")
.foregroundColor(.gray)
.imageScale(.large)
Text("Settings")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color(red: 32/255, green: 32/255, blue: 32/255))
.edgesIgnoringSafeArea(.all)
}
}

Button appears on top but not pressable

public struct Frontside: View
{
#Binding public var kanatext: String
public var body: some View
{
ZStack{
RoundedRectangle(cornerRadius: 25, style: .continuous)
.foregroundColor(Color.red)
.frame(width: 160, height: 160)
.zIndex(0)
Text(self.kanatext)
.font(.title)
.fontWeight(.black)
.padding(50)
.zIndex(1)
VStack {
Spacer()
HStack {
Button(action: {
print("button pressed")
}) {
Image(systemName: "xmark.circle")
.font(.title)
}
.mask(Circle())
.opacity(0.4)
Button(action: {
print("button pressed")
}) {
Image(systemName: "checkmark.circle")
.font(.title)
}
.mask(Circle())
.opacity(0.4)
}
}
.zIndex(2)
}
}
}
In the above code snippet, I have used a Zstack to layer different parts of a flash card, a background, the text, and then correct/incorrect buttons. The uppermost layer are the buttons, which appear correctly, but for some reason they are not actually pressable.
Have you tried using onTapGesture? It might have to do with the fact that you're using a ZStack.
Try something like:
Image(systemName: "checkmark.circle")
.font(.title)
.onTapGesture {
print("button pressed")
}
In this case there would be no needed to wrap the Image in a Button.
If this doesn't work add onTapGesture to your VStack and have it be empty.