SwiftUI tvOS Button - Parallax? - button

Working with the landmark-Sample code from Apple.
I got my app running like this:
https://youtu.be/CLL_oknQEDI?t=1118
However, how is it possible to achieve the "parallax"-effect on the buttons/navigationLinks?
If you are on the focused button, you can't wiggle it. Like on all other AppleTV buttons in store etc. Didn't find any modifier to do so on Buttons or Navigationlinks.
All i found is this forum post: https://forums.developer.apple.com/thread/124684
VStack(alignment: .leading) {
Button(action: {
print("Tapped item")
}) {
landmark.image
.renderingMode(.original)
.resizable()
.frame(width: 255, height: 155)
.cornerRadius(5)
Text(landmark.name)
.foregroundColor(.primary)
.font(.caption)
}
}

Related

While using a ForEach nested in a LazyVGrid how can I implement usable play buttons that navigate to a different view?

I have created a scrollable grid view where each icon is supposed to represent a different playlist. I implemented a play button using a navigation link for each playlist in the left corner however, for some reason, the play button is not usable. It does not work in the preview or the simulator. In other words, the play button does not allow me to click it and navigate to another view.
Here is the code I have:
var body: some View {
ZStack {
ScrollView {
LazyVGrid (columns: [GridItem(.fixed(200)), GridItem(.fixed(200))]) {
ForEach(musics) { sub in
ZStack (alignment: .topLeading){
VStack(alignment: .leading) {
Image(sub.albumImage)
.resizable()
.frame(width: 150, height: 150)
.mask(RoundedRectangle(cornerRadius: 20))
Text(sub.albumGen)
.fontWeight(.bold)
.foregroundColor(.white)
Text(sub.songs)
.foregroundColor(.white)
} // END OF VSTACK
NavigationLink {
// Naviagte to a different view!
CategoryView()
} label: {
Image(systemName: "play.circle")
.font(.system(size: 30))
.padding()
}
} // END OF ZSTACK
}// END OF FOR EACH
} // END OF GRID ITEM
} // END OF SCROLL VIEW
} //END OF ZSTACK
}
}
Here is an image of how it looks in the preview and simulator:
I have circled the play buttons because it is hard to see. Usually, when I use a navigation link, the buttons appear blue and are clickable.
How can I edit my code so that the navigation link is active and navigates to a different view?
Embed your View in a NavigationView, which is required for NavigationLink to work.

SwiftUI Button tap area not accurate but in navigationBarItems is right

Here use the same button view in navigationbaritem and ContentView.
have idea to solve this problem?
https://imgur.com/a/jCxfVSa
struct myButton: View {
var body: some View {
Button(action: { print("qwe\(Int.random(in: 1...100))") }) {
Image( "play")
.resizable()
.scaledToFit()
.background(Color.red)
}
.frame(width: 40, height: 40, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
}
}
struct ContentView: View {
var body: some View {
NavigationView {
myButton()
.navigationBarItems(leading:
myButton()
)
.navigationTitle("Title")
.navigationBarTitleDisplayMode(.inline)
}
}
enter image description here
Natively in SwiftUI you can't use shaping on toolbar icons
(you can, but sometimes navigation bar icons loses clipshapes (after navigationLink, .sheet, .alert....)
(on SwiftUI 2 prefer to use .toolbar{}, no .navigationBarItems() )
But, you can use SwiftUIX library on GitHub

Tappable Image in a ZStack with a Button

I have a ZStack with an image and a close button overlaying it. I cannot make the image tappable with the button overlaying it.
ZStack(alignment: .topTrailing) {
NetworkImage(url: article.imageURL)
.aspectRatio(contentMode: .fill)
.frame(width: UIScreen.main.bounds.width,
height: UIScreen.main.bounds.height * 0.5)
.scaleEffect(scrollViewContentOffset < 0 ?
1 + (-scrollViewContentOffset * 0.005)
: 1,
anchor: .bottom)
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}){
Image(systemName: "xmark.circle.fill")
.foregroundColor(.init(white: 0.9)).padding([.top, .trailing])
.font(.system(size: topCloseButtonSize))
.offset(y: scrollViewContentOffset < 0 ?
.extraLarge + scrollViewContentOffset :
.extraLarge)
}
}
I have tried to add a tap gesture to the Image itself but that disables the tapability on the close button. How can I keep the ZStack in tact and have both the image and close button tappable?
Try adding an onTapGesture modifier to the NetworkImage (Rectangle in the code beloew) - it seems to work as expected then. I simplified the NetworkImage to use a standard Rectangle, but the tap results should be the same. Tested on Xcode 12.1.
ZStack(alignment: .topTrailing) {
Rectangle() // Use NetworkImage here - simplified to Rectangle for testing
.aspectRatio(contentMode: .fill)
.frame(width: UIScreen.main.bounds.width,
height: UIScreen.main.bounds.height * 0.5)
.onTapGesture(count: 1, perform: {
print("RECTANGLE TAPPED!")
})
Button(action: {
print("CLOSE TAPPED")
}){
Image(systemName: "xmark.circle.fill")
.foregroundColor(.init(white: 0.9)).padding([.top, .trailing])
}
}

swiftui open view from menu button

I am trying to do something very basic, but I have been through the official tutorials, and through dozens of stack overflow posts. I am trying to open an activity from a menu button. I do want the standard navigation back arrow when I do this.
var body: some View {
NavigationView {
VStack(alignment: .leading) {
Text("Hello World!")
.toolbar {
ToolbarItem(placement: .primaryAction) {
Menu {
Button(action: {
Activities()
}) {
Label("Activities", systemImage: "doc")
}
"Activities()" is my view. When I do this nothing happens. I have read in other posts that you cannot have a navigation link in a menu either, which would be fine if that worked. How do I programmatically open up a view so the back arrow works?
Thank you
In this case where you want to open a view but can't use a NavigationLink directly you can use it in another place and activate it programmatically from the button via a State property:
#State private var isShowingDetailView = false
var body: some View {
NavigationView {
VStack(alignment: .leading) {
NavigationLink(destination: Activities(), isActive: $isShowingDetailView) {
EmptyView()
}
Text("Hello World!")
.toolbar {
ToolbarItem(placement: .primaryAction) {
Menu {
Button(action: {
isShowingDetailView = true
}) {
Label("Activities", systemImage: "doc")
}
}
}
}
}
}

Why does my Button style object only work on the text within the button and not the entire button?

I have below a ButtonStyle object that I wish to use when a Button is tapped. However, when I call it on my Button, the effect is seen only on the text within the button and not on the entire Button as a whole.
I have tried calling it outside but to no avail. Can someone please explain to me how I can fix my error?
Button(action: {
}) {
Text("Button")
.foregroundColor(.white)
}.background(Color.red)
.buttonStyle(ScaleButtonStyle())
struct ScaleButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.scaleEffect(configuration.isPressed ? 5 : 1)
}
}
EDIT:
Button(action: {}) {
Text("Button")
.fontWeight(.semibold)
.foregroundColor(.white)
.font(.title)
}
.buttonStyle(ScaleButtonStyle(bgColor: Color.red))
.frame(width: geo.size.width*0.8, height: geo.size.height*0.1, alignment: .center)
.background(Color.red)
.clipShape(Rectangle())
struct ScaleButtonStyle: ButtonStyle {
let bgColor: Color
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.background(bgColor)
.scaleEffect(configuration.isPressed ? 5 : 1)
}
}
The solution is to make background as part of a button style as shown below.
Tested with Xcode 11.4 / iOS 13.4
struct ScaleButtonStyle: ButtonStyle {
let bgColor: Color
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.background(bgColor)
.scaleEffect(configuration.isPressed ? 5 : 1)
}
}
struct TestScaleButtonStyle: View {
var body: some View {
Button(action: { }) {
Text("Button")
.foregroundColor(.white)
}.buttonStyle(ScaleButtonStyle(bgColor: Color.red))
}
}

Resources