I want to work with an image that you take with camera, explicitly, I want work with matrix image, change pixel...
That's my code which allow you to take a picture.
import SwiftUI
struct ContentView: View {
#State private var showImagePicker: Bool = false
#State private var image: Image? = nil
var body: some View {
VStack {
image?.resizable()
.scaledToFit()
.padding(.top,100)
.frame(width: 300.0, height: 300.0, alignment: .top)
Button(action: {self.showImagePicker = true
}) {HStack {
Image(systemName: "camera.on.rectangle.fill")
.font(.title)
Text("Take picture")
.fontWeight(.semibold)
.font(.title)
}
.padding()
.background(Color.red)
.foregroundColor(.white)
.cornerRadius(40)}
}
.padding(.bottom,400)
.sheet(isPresented: self.$showImagePicker) {
PhotoCaptureView(showImagePicker: self.$showImagePicker, image: self.$image)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Here is PhotoCaptureView
import Foundation
import SwiftUI
struct PhotoCaptureView: View {
#Binding var showImagePicker: Bool
#Binding var image: Image?
var body: some View {
ImagePicker(isShown: $showImagePicker, image: $image)
}
}
#if DEBUG
struct PhotoCaptureView_Previews: PreviewProvider {
static var previews: some View {
PhotoCaptureView(showImagePicker: .constant(false), image: .constant(Image("")))
}
}
#endif
I have to return the image, I guess that it is in struct PhotoCaptureView.
How to retrieve this image and work with ?
Thank you.
You can use onDismiss completionHandler of the sheet to work on image after it is selected.
.sheet(isPresented: Binding<Bool>.constant(true), onDismiss: {
if let image = self.image {
processor.process(image)
}
}, content: { () -> View in
PhotoCaptureView(showImagePicker: self.$showImagePicker, image: self.$image)
})
Related
I would like to create a modal sheets with an image in the body, like in Human Interface Guidelines. Could you please give me an example?
https://developer.apple.com/design/human-interface-guidelines/watchos/interaction/modality/
The following code basically recreates the example screenshot from above:
import SwiftUI
struct ModalView: View {
#Binding var isPresented: Bool
var body: some View {
VStack {
Image(systemName: "headphones")
.font(.system(size: 30))
Text("To play audio, connect Bluetooth headphones to your Apple Watch.")
.font(.footnote)
.multilineTextAlignment(.center)
}
.opacity(0.8)
.padding(10)
Spacer()
Button("Connect a Device") {
isPresented.toggle()
}.padding(.horizontal)
}
}
struct TestView: View {
#State private var isPresentingModalView = false
var body: some View {
Button("Connect") {
isPresentingModalView.toggle()
}
.fullScreenCover(isPresented: $isPresentingModalView) {
ModalView(isPresented: $isPresentingModalView)
}
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
Result:
See docs:
https://developer.apple.com/documentation/swiftui/view/fullscreencover(ispresented:ondismiss:content:)
I am trying to implement a simple "tap to toggle the visibility of the UI" in SwiftUI with fade in/out animation. The following code animates the fade-in effect of the Text element as I expected, but it immediately hides the Text element when isVisible become false.
I'd like to understand why this code does not work, and how to fix it in the most natural way.
import SwiftUI
struct ContentView: View {
#State var isVisible = true
var body: some View {
ZStack {
Rectangle()
.foregroundColor(.blue)
.gesture(TapGesture(count: 1).onEnded {
withAnimation(.easeInOut(duration: 1.0)) {
isVisible.toggle()
}
})
if isVisible {
Text("Tap me!")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I'm using Xcode 12.5 on Big Sur, and my iPhone is running iOS 14.5.1.
Thanks to Erik Philips, here is the answer.
import SwiftUI
struct ContentView: View {
#State var isVisible = true
var body: some View {
ZStack {
Rectangle()
.zIndex(1)
.foregroundColor(.blue)
.gesture(TapGesture(count: 1).onEnded {
withAnimation(.easeInOut(duration: 1.0)) {
isVisible.toggle()
}
})
if isVisible {
Text("Tap me!")
.zIndex(2)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I am trying to pass data (incomeAmount) from the First View to the Second View in my SwiftUI app, but I need to declare the BindingString. What does it mean that I need to declare the BindingString?
View 1
struct ContentView: View {
#State var incomeAmount = ""
var body: some View {
NavigationView {
VStack {
TextField("Your income amount", text: $incomeAmount)
.frame(width: 300)
.padding(.bottom, 30)
NavigationLink(destination: NewView()){
Text("Continue")
.frame(width: 300, height: 50, alignment: .center)
.background(Color.black)
.cornerRadius(130)
.foregroundColor(.white)
.padding(.bottom, 30)
}
Text("$\(incomeAmount)")
}.navigationTitle("First View")
}
}
}
View 2
struct NewView: View {
#Binding var incomeAmount: String
var body: some View {
NavigationView {
VStack {
Text("$\(incomeAmount)")
}
}.navigationTitle("Second View")
}
}
struct NewView_Previews: PreviewProvider {
static var previews: some View {
NewView(incomeAmount: <#Binding<String>#>)
}
}
To pass the incomeAmount to the second view, you have to do this:
NavigationLink(destination: NewView(incomeAmount: $incomeAmount)) { ... }
Also, you need to provide it to:
struct NewView_Previews: PreviewProvider {
static var previews: some View {
NewView(incomeAmount: .constant("something here"))
}
}
Because in PreviewProvider, NewView expect to have a Binding<String> passed in. So you need to provide it.
How can I preview this button who needs a PresentationMode to get constructed?
The button works well the main view that contains it creates it with an environment PresentationMode object declared as:
#Environment(\.presentationMode) var presentationMode:Binding<PresentationMode>
struct BackButton: View {
#Binding var presentationMode: PresentationMode
var color: Color
var body: some View {
Button(action: {
self.$presentationMode.wrappedValue.dismiss()
}, label: { Image(systemName: "chevron.left")
.scaleEffect(1.3)
.foregroundColor(color)
.offset(x: -17)
.frame(width: 43, height: 43)
}
)
}
}
struct BackButton_Previews: PreviewProvider {
static var previews: some View {
let pres = PresentationMode()
return BackButton(presentationMode: pres, color: .black) // Compiler Error: PresentationMode cannot be constructed because it has no accessible initializers
}
}
I think PresentationMode should be declared as Environment Variable.
So declare it like this..
#Environment(\.presentationMode) var presentationMode
and then change it on action like that, as it is not a Binding anymore.
Button(action: {
self.presentationMode.wrappedValue.dismiss()
Edit:
Here is a working example/ with preview for BackButton View and how to use PresentationMode.
struct MainView: View {
var body: some View {
NavigationView
{
VStack()
{
Text("Hello World")
NavigationLink("Go to Detail View", destination: BackButton(color: .black))
}.navigationBarTitle(Text("Main View"))
}
}
}
struct BackButton : View
{
//Environment variable here
#Environment(\.presentationMode) var presentationMode
var color: Color
var body: some View
{
Button(action: {
//Dismiss the View
self.presentationMode.wrappedValue.dismiss()
}, label: { Image(systemName: "chevron.left")
.scaleEffect(1.3)
.foregroundColor(color)
.offset(x: -17)
.frame(width: 43, height: 43)
})
}
}
struct BackButton_Previews: PreviewProvider {
static var previews: some View {
//Preview here is working, no need to pass environment variable
//Going back from this view in Preview won't work
BackButton(color: .black)
}
}
I have a view that is triggered by a button touch. It appears nicely, all good. Now I want the View to disappear automatically again after a few seconds.
The view should disappear automatically without having to hit the button again.
Below my test project
import SwiftUI
struct ContentView: View {
#State private var presentClipboardView = false
#State private var scale: CGFloat = 1.0
var body: some View {
VStack{
Button(action: {
let pasteboard = UIPasteboard()
pasteboard.string = "http://I_AM_A_URL.com"
withAnimation(.easeInOut(duration: 2)) {
self.presentClipboardView.toggle()
}
}, label: {
HStack {
Image(systemName: "list.dash")
.padding(.trailing)
VStack(alignment: .leading) {
Text("Open URL")
.font(.headline)
}
Spacer()
}
}
)
if(self.presentClipboardView){
LabelView()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct LabelView: View {
var body: some View {
Text("URL copied to clipboard!")
.padding(10)
.font(.title)
.foregroundColor(.white)
.background(RoundedRectangle(cornerRadius: 8).fill(Color.green).shadow(color: .gray, radius: 3))
}
}
Try this on LabelView()
LabelView().onAppear {
Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { timer in
withAnimation(.easeInOut(duration: 2)) {
self.presentClipboardView.toggle()
}
}
}
lets try
import SwiftUI
struct ContentView: View {
#State var flag = false
let time = 3.0
var body: some View {
VStack {
if flag {
DetailView(flag: $flag, showTime: time)
}
Button(action: {
self.flag.toggle()
}) {
Text("show for \(time.description) seconds")
}.disabled(flag)
}
}
}
struct DetailView: View {
#Binding var flag: Bool
let showTime: Double
var body: some View {
Text("Welcome").font(.largeTitle).foregroundColor(Color.orange)
.onAppear {
let _delay = RunLoop.SchedulerTimeType(.init(timeIntervalSinceNow: self.showTime))
RunLoop.main.schedule(after: _delay) {
self.flag.toggle()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}