Let View disappear automatically

Hi,


I have a view that is triggred by a button touch. It appears nicely, all good. Now I want the View to disappear automatically again after a few seconds. How do I do that?!


Below my test project


//
//  ContentView.swift
//  FadeOut
//
//  Created by Max on 2020-03-19.
//  Copyright © 2020 Max. All rights reserved.
//

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))
  }
}

Replies

hi,


how about setting a timer when the LabelView() appears, and then resetting presentClipboardView to false with animation? i think the following works in my test:


(1) add the .onAppear modifier to LabelView() in line 39


if(self.presentClipboardView){
  LabelView()
    .onAppear(perform: setDismissTimer)
}


(2) and add this new function to ContentView:


func setDismissTimer() {
  let timer = Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { timer in
    withAnimation(.easeInOut(duration: 2)) {
      self.presentClipboardView = false
    }
    timer.invalidate()
  }
  RunLoop.current.add(timer, forMode:RunLoop.Mode.default)
}


hope this helps,

DMG

Hi DMG,


Thanks! I was posting the question also on SO and there the feedback was to use


LabelView().onAppear {
  Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { timer in
  withAnimation(.easeInOut(duration: 2)) {
  self.presentClipboardView.toggle()
  }
  }
  }


without the


  RunLoop.current.add(timer, forMode:RunLoop.Mode.default) 


So my question is: is there a specific reason to use the RunLoop or is it just a different approach?

hi,


i pulled the syntax i used from something else that's a little older; i believe the syntax you found is equivalent (i explicitly created the timer and added it to the run loop).


i think there's also no need to explicitly invalidate() the timer as i did -- it fires only once and is immediately invalidated (whereas the situation i pulled this from involved a repeating timer).


hope this helps,

DMG