swiftUI transitions: Scale from some frame - like iOS Homescreen is doing when opening an App

后端 未结 2 558
鱼传尺愫
鱼传尺愫 2020-12-09 07:25

How do I get the effect in a translation, that iOS home screen does when opening an App: It scales the App to fullscreen, starting from the App-icon on the home screen?

相关标签:
2条回答
  • 2020-12-09 07:31

    The above sample code should give you an idea on scaling an image

    
    struct ImageCustomScaling: View {
        // image to be scaled
        var scaleImage: Image
    
        // scale ratio
        var scaleTo: Double
    
        @State private var start = false
    
        var body: some View {
    
            VStack {
    
                scaleImage
                    .font(.title)
                    .scaleEffect(self.start ? CGFloat(scaleTo) : 1)
                    .opacity(self.start ? 1 : 0)
                    .animation(Animation.interpolatingSpring(stiffness: 25, damping: 5, initialVelocity: 10).delay(0.9))
    
            }
            .foregroundColor(.blue)
            .onAppear {
                self.start = true
            }
        }
    
    }
    
    

    Above can be called by something like below

    ImageCustomScaling(scaleImage: Image(systemName: "cloud.fill"), scaleTo: 5 )
    

    Added animation modifier to give visual cue. You can change it to meet your needs.

    0 讨论(0)
  • 2020-12-09 07:40

    Here is a demo of idea how such effect could be done with combined transitions... (positions and sizes are hardcoded for demo simplicity - they can be read with geometry reader, alignment guides or anchor preferences, and actually do not affect the transition usage idea, also animation can be configured)

    Demo:

    SwiftUI view from button

    struct TestRisingView: View {
    
        let screen = UIScreen.main.bounds
    
        @State var showingView = false
        @State var btFrame: CGRect = .zero
    
        var body: some View {
            GeometryReader { g in
                ZStack {
                    Rectangle().fill(Color.clear)
    
                    self.activatingButton(frame: CGRect(x: 80, y: 30, width: 60, height: 40))
                    self.activatingButton(frame: CGRect(x: self.screen.maxX - 80, y: 30, width: 60, height: 40))
                    self.activatingButton(frame: CGRect(x: self.screen.maxX - 80, y: self.screen.maxY - 60, width: 60, height: 40))
                    self.activatingButton(frame: CGRect(x: 80, y: self.screen.maxY - 60, width: 60, height: 40))
    
                    if self.showingView {
                        self.topView
                            .zIndex(1)
                            .transition(
                                AnyTransition.scale(scale: 0.12).combined(with:
                                AnyTransition.offset(x: self.btFrame.origin.x - g.size.width/2.0,
                                                     y: self.btFrame.origin.y - g.size.height/2.0))
                            )
                    }
                }
            }
        }
    
        func activatingButton(frame: CGRect) -> some View {
            Button(action: {
                withAnimation {
                    self.btFrame = frame
                    self.showingView.toggle()
                }
            }) {
                Text("Tap")
                    .padding()
                    .background(Color.yellow)
            }
            .position(frame.origin)
        }
    
        var topView: some View {
            Rectangle()
                .fill(Color.green)
                .frame(width: 300, height: 400)
        }
    }
    
    struct TestRisingView_Previews: PreviewProvider {
        static var previews: some View {
            TestRisingView()
        }
    }
    
    0 讨论(0)
提交回复
热议问题