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])
}
}
Related
I want to add 2 buttons on a map in swiftUI Map to zoom in and out of it. I have positioned the two buttons at the bottom of the screen in a Stack inside a VStack. I need the code to make them work.
This is what I have:
import Foundation
import SwiftUI
import MapKit
struct QuakeDetail: View {
var quake: Quake
#State private var region : MKCoordinateRegion
init(quake : Quake) {
self.quake = quake
_region = State(wrappedValue: MKCoordinateRegion(center: quake.coordinate,
span: MKCoordinateSpan(latitudeDelta: 3, longitudeDelta: 3)))
}
var body: some View {
ZStack {
VStack {
Map(coordinateRegion: $region, annotationItems: [quake]) { item in
MapMarker(coordinate: item.coordinate, tint: .red)
} .ignoresSafeArea()
HStack {
Button {
print ("pressed +")
} label: {
HStack {
Text("map")
Image(systemName: "plus")
}
}.padding(5).border(Color.blue, width: 1)
Spacer()
QuakeMagnitude(quake: quake)
Spacer()
Button {
print ("pressed -")
} label: {
HStack {
Text("map")
Image(systemName: "minus")
}
}.padding(5).border(Color.blue, width: 1)
}.padding()
Text(quake.place)
.font(.headline)
.bold()
Text("\(quake.time.formatted())")
.foregroundStyle(Color.secondary)
Text("\(quake.latitude) \(quake.longitude)")
}
}
}
}
You have to operate with span parameter of MKCoordinateRegion for that (the less value the more zoomed area), like (demo zoom on 10%):
Button("Zoom In") {
region.span.latitudeDelta *= 0.9
region.span.longitudeDelta *= 0.9
}
Tested with Xcode 13.2 / iOS 15.2
I have added the borders for all sides using code below in SwiftUI. I want to trim stroke a particular position like below.
Want to achieve:-
Output:-
Code:-
import SwiftUI
struct RoundTrimImage: View {
var body: some View {
VStack{
Button(action: {
print("Round Action")
}) {
Text("Press")
.frame(width: 100, height: 100)
.foregroundColor(Color.black)
.background(Color.red)
.clipShape(Circle()).padding(5)
.overlay(
RoundedRectangle(cornerRadius: 100)
.trim(from: 0, to: CGFloat(0.8))
.stroke(Color.blue, lineWidth: 2)
)
}
}
}
}
Question: Can someone please explain to me how to trim stoke particular position, I've tried with above code but no results yet.
Can someone please explain to me How to get Progress?
Any help would be greatly appreciated.
Thanks in advance.
The possible approach is to prepare needed shape using Arc and then rotate it to what ever position needed.
Demo prepared with Xcode 13.2 / iOS 15.2
struct DemoView: View {
var body: some View {
VStack{
Button(action: {
print("Round Action")
}) {
Text("Press")
.frame(width: 100, height: 100)
.foregroundColor(Color.black)
.background(Color.red)
.clipShape(Circle()).padding(5)
.overlay(
RotatedShape(shape: CutShape(), angle: .degrees(-120))
.stroke(Color.blue, lineWidth: 2)
)
}
}
}
}
private struct CutShape: Shape {
func path(in rect: CGRect) -> Path {
Path {
$0.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rect.midY, startAngle: Angle(degrees: -5), endAngle: Angle(degrees: 5), clockwise: true)
}
}
}
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
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))
}
}
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)
}
}