SwiftUI: replacing custom map button with a MapPin as a button? - swiftui

I was using a custom button on a map but I realized now I want to use a normal pin, such as MapPin. How can I change my code to adjust for the use of MapPin so that when I click on it, the same actions take place .
Map(coordinateRegion: $region, annotationItems: getAnnotated()) { item in
MapAnnotation(coordinate: item.coordinate) {
Button(action: {
selected.item = item // <--- here
showSheet.toggle()
}){
Image("icon")
.resizable()
.frame(width: 70, height: 70)
.foregroundColor(.white)
.cornerRadius(9.0)
}
.background(Circle())
.foregroundColor(Color.green)
}
}
I tried swapping out Image() for MapPin() as a last ditch effort but that didn't work.

you could try this:
Map(coordinateRegion: $region, annotationItems: getAnnotated()) { item in
MapAnnotation(coordinate: item.coordinate) {
Button(action: {
selected.item = item
showSheet.toggle()
}){
Image(systemName: "mappin.and.ellipse") // <---
.scaleEffect(2.0)
.foregroundColor(.red)
.padding()
}
.background(Circle())
.foregroundColor(Color.clear) // <---
}
}
or "mappin.circle", "mappin"
and adjust the colors as you see fit.

Related

how to use bottom sheet transparent background in swiftui like dialog?

I am using the bottom sheet. When the bottom opens, it covers the whole page over the parent. I want to use a bottom sheet like an alert dialog transparent. Thant means parent content not covered whole
here is the image:
The green portion is the content of the bottom sheet. But it covered the whole page.
Here is the code:
calling bottom sheet:
struct CustomDialogSV: View {
#State private var showSheet = false
var body: some View {
Button("Show Sheet") {
self.showSheet = true
}
.sheet(isPresented: $showSheet) {
ZStack {
Color.clear
.edgesIgnoringSafeArea(.all)
CustomAlert()
.background(Color.red)
.cornerRadius(10)
.shadow(radius: 10)
.padding()
// .center()
}
}
}
}
Bottom sheet:
struct CustomAlert: View {
var body: some View {
VStack(alignment: .leading) {
Text("Alert Title")
.font(.headline)
.padding(.bottom)
Text("This is the alert message. It can be any amount of text.")
.padding(.bottom)
HStack {
Button(action: {
// handle action for first button
}) {
Text("First Button")
}
.padding(.trailing)
Button(action: {
// handle action for second button
}) {
Text("Second Button")
}
}
}
.padding()
.background(Color.green)
.cornerRadius(10)
.shadow(radius: 10)
}
}
Is it possible to remove the background without green portions?

Problem implementing scrollTo in SwiftUI using Slider and Button

I'm trying to reposition a list using scrollTo with a Slider and Button and have 2 problems. The list has Sections with id's and nested Texts below, so the scrolling (by Slider or Button) is to the Section heads only.
Here are the problems:
Slider works fine except that the animation briefly shows the list at the top (you can see the navigationTitle go to full size) before it scrolls to the desired position correctly.
The Button moves the Slider but appears to not find the id's in the Section, so it doesn't reposition to the right Section.
Anyone have any ideas?
struct Floors: Identifiable {
let id: String
let name: String
}
struct UnitLine: Identifiable {
let id=UUID()
let name: String
}
struct UnitKeyboardView: View {
#Environment(\.presentationMode) var presentationMode
#State private var sliderValue = 8.0
var body: some View {
let floors=[Floors(id:"8",name:"8"),Floors(id:"9",name:"9"),Floors(id:"10",name:"10"),Floors(id:"11",name:"11"),Floors(id:"12",name:"12"),Floors(id:"13",name:"13"),Floors(id:"14",name:"14"),Floors(id:"15",name:"15"),Floors(id:"16",name:"16"),Floors(id:"17",name:"17"),Floors(id:"18",name:"18"),Floors(id:"19",name:"19"),Floors(id:"20",name:"20"),Floors(id:"21",name:"21"),Floors(id:"22",name:"22"),Floors(id:"23",name:"23"),Floors(id:"24",name:"24"),Floors(id:"25",name:"25"),Floors(id:"26",name:"26"),Floors(id:"27",name:"27"),Floors(id:"28",name:"28"),Floors(id:"29",name:"29")]
let unitlines=[UnitLine(name:"01"),UnitLine(name:"02"),UnitLine(name:"03"),UnitLine(name:"04"),UnitLine(name:"05"),UnitLine(name:"06"),UnitLine(name:"07"),UnitLine(name:"08")]
NavigationView {
ScrollViewReader {proxy in
VStack {
Spacer()
List {
ForEach(floors) { i in
Section(header: Text("Floor \(i.name)")) {
ForEach(unitlines) { u in
Text(u.name)
.padding(.trailing,200)
.contentShape(Rectangle())
.onTapGesture {
print("tapped")
presentationMode.wrappedValue.dismiss()
}
}
}
}
}
HStack {
Spacer()
Text("Flr: \(Int(sliderValue))")
.font(.title)
.padding(10)
Button {
if sliderValue>8 {
sliderValue=sliderValue-1.0
proxy.scrollTo(String(Int(sliderValue)), anchor: .topLeading)
}
else { print("slider below (\(sliderValue))") }
print(proxy)
} label: {
Image(systemName: "minus")
}
.frame(width:30, height:15)
.padding(10)
.background(Color.red)
.clipShape(Capsule())
Slider(value: $sliderValue, in: 8...42, step: 1.0, onEditingChanged: {_ in
withAnimation {
proxy.scrollTo(String(Int(sliderValue)), anchor: .topLeading)
print(String(Int(sliderValue)))
}
}
)
.background(Color.cyan)
.border(Color.blue, width: 1)
.padding(10)
Button {
if sliderValue<42 {
print(sliderValue)
sliderValue=sliderValue+1.0
print(sliderValue)
proxy.scrollTo(String(Int(sliderValue)), anchor: .topLeading)
}
} label: {
Image(systemName: "plus")
}
.frame(width:30, height:15)
.padding(10)
.background(Color.green)
.clipShape(Capsule())
Spacer()
}
.background(Color.gray)
}
}
.navigationTitle("Select Address")
}
}
}

Detect if user tapped the screen, including Buttons, in SwiftUI

I've been trying to use .onTapGesture to detect if the user taps on the screen. However, I noticed that it doesn't get triggered if the user taps on actionable elements like buttons and pickers. Is there a way to detect if the user taps on the screen, including these actionable elements without having to manually call my viewTapped function for each button, picker, etc. separately?
Here's the code I used to test this.
struct ContentView: View {
#State var mode = 0
var body: some View {
ZStack {
VStack {
Text("Hello, world!")
.padding()
Picker(
selection: $mode,
label: Text("Picker")) {
Text("Option 1").tag(0)
Text("Option 2").tag(1)
}
.pickerStyle(SegmentedPickerStyle())
.frame(width: 200)
.foregroundColor(.white)
.padding()
Button {
print("button clicked")
} label: {
Text("Click me")
}
.padding()
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.green)
.onTapGesture {
viewTapped()
}
}
public func viewTapped() {
print("view tapped")
}
}
If you need to detect touches simultaneity, you need the simultaneousGesture modifier instead. like:
.simultaneousGesture(
TapGesture()
.onEnded {
viewTapped()
}
)

Dismiss button (X) on an image - top right alignment HOW?

What is an effective & effecient way to get the Dismiss button (X) into the top right corner?
I'm struggling with container alignment... can't say I GROK it.
Needless to say ... this ain't it!
var body: some View {
ZStack {
Image("Biz-card_2020")
.resizable()
.edgesIgnoringSafeArea(.all)
HStack(alignment: .top) {
VStack() {
Spacer(minLength: 5) // vertical space
HStack() {
Spacer()
// close Welcome page (X) button
Button(action: {
//print(" - Button to dismiss page \(self.isPresented)")
self.isPresented = false // dismiss the Welcome view
//print(" - after action Button to dismiss Welcome page \(self.isPresented)")
}, label: {
Image(systemName: "xmark.circle" )
.scaledFont(name: "Georgia", size: Const.titleText)
.minimumScaleFactor(0.3)
.accentColor(.white)
.padding(10)
})
}
Spacer()
}
}
}
}
You need to remove Spacer(minLength: 5) and replace it with padding for HStack.
Spacer(minLength: 5) doesn't mean its length will be exactly 5 (only that the minimum length will be 5).
You may also want to extract close button to another function for clarity.
Try the following:
struct ContentView: View {
...
var body: some View {
ZStack {
Image("Biz-card_2020")
.resizable()
.edgesIgnoringSafeArea(.all)
closeButton
}
}
var closeButton: some View {
VStack {
HStack {
Spacer()
Button(action: {
...
}) {
Image(systemName: "xmark.circle")
.padding(10)
}
}
.padding(.top, 5)
Spacer()
}
}
}
ZStack can be configured using .topTrailing etc. You should use those alignments to configure your view. Using something like Spacer() is going to cause the rest of your views to get pushed down.
ZStack(alignment: .topTrailing) {
// your code here
}
If you need to move your code a bit more, use either padding, or offset modifiers.

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.