Dialog 出现消失动画和位置

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dialog 出现消失动画和位置相关的知识,希望对你有一定的参考价值。

参考技术A 拿到Dialog的实例, dialog.getWindow().getAttributes().windowAnimations = R.style.PauseDialogAnimation; 完成动画的设置。
style

缩放+透明度
@anim/grow_in

@anim/grow_out

从上到下
IN

OUT

从左到右
in

out

显示位置有 Window window = dialog.getWindow();window.setGravity(Gravity.BOTTOM|Gravity.LEFT);
下左,,和Framelayout是一样的定位方式。

dialog有两个回调函数, setOnShowListener 和 setOnDismissListener ,可以通过这两个函数还显示和消失的时候,对dialog中的view,进行动画。更富有动感。

调整键盘出现/消失的视图:动画曲线问题

【中文标题】调整键盘出现/消失的视图:动画曲线问题【英文标题】:Adjusting a view for keyboard appearing/disappearing: problem with animation curve 【发布时间】:2020-04-04 01:32:32 【问题描述】:

我正在尝试创建一个 SwiftUI 视图修改器,它添加底部填充以响应屏幕键盘的出现或消失。这是我正在使用的方法:

struct KeyboardAdjustingModifier: ViewModifier 
    @ObservedObject private var responder = KeyboardResponder()

    func body(content: Content) -> some View 
        GeometryReader  proxy in
            content
                .padding(.bottom, self.bottomPadding(in: proxy))
        
    

    func bottomPadding(in proxy: GeometryProxy) -> CGFloat 
        if responder.endFrame == .zero 
            return 0
         else 
            return max(0, proxy.frame(in: .global).maxY - self.responder.endFrame.minY)
        
    


fileprivate final class KeyboardResponder: ObservableObject 
    @Published var endFrame: CGRect = .zero

    init(notificationCenter: NotificationCenter = .default) 
        notificationCenter.addObserver(self,
                                       selector: #selector(keyboardWillShowOrChangeFrame(notification:)),
                                       name: UIResponder.keyboardWillShowNotification, object: nil)
        notificationCenter.addObserver(self,
                                       selector: #selector(keyboardWillShowOrChangeFrame(notification:)),
                                       name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
        notificationCenter.addObserver(self,
                                       selector: #selector(keyboardWillHide(notification:)),
                                       name: UIResponder.keyboardWillHideNotification, object: nil)
    

    @objc private func keyboardWillShowOrChangeFrame(notification: Notification) 
        withAnimation(Animation(curve: notification.animationCurve, duration: notification.duration)) 
            endFrame = notification.endFrame
        
    

    @objc private func keyboardWillHide(notification: Notification) 
        withAnimation(Animation(curve: notification.animationCurve, duration: notification.duration)) 
            endFrame = .zero
        
    

    struct Info 
        let curve: UIView.AnimationCurve
        let duration: TimeInterval
        let endFrame: CGRect
    


fileprivate extension Animation 
    init(curve: UIView.AnimationCurve, duration: TimeInterval) 
        switch curve 
        case .easeInOut:
            self = .easeInOut(duration: duration)
        case .easeIn:
            self = .easeIn(duration: duration)
        case .easeOut:
            self = .easeOut(duration: duration)
        case .linear:
            self = .linear(duration: duration)
        @unknown default:
            self = .easeInOut(duration: duration)
        
    


fileprivate extension Notification 
    var animationCurve: UIView.AnimationCurve 
        guard let rawValue = (userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? Int) else 
            return UIView.AnimationCurve.linear
        

        return UIView.AnimationCurve(rawValue: rawValue)!
    

    var duration: TimeInterval 
        userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval ?? 0
    

    var endFrame: CGRect 
        userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect ?? .zero
    

我遇到的问题是 SwiftUI 动画曲线似乎与键盘的动画曲线完全不同:

有谁知道是否可以像这样将 SwiftUI 动画与 UIKit 同步?我将通知的 userInfo 中的动画曲线信息映射到 SwiftUI 动画曲线的方式很可能存在错误。还是我应该考虑另一种解决这个问题的方法?

我尝试的另一件事是使用UIHostingController 直接在 UIKit 中处理动画。它与键盘正确同步,但如果 SwiftUI 也在同时为内容制作动画,我在我的动画块中调用 layoutIfNeeded 时遇到了崩溃。

【问题讨论】:

【参考方案1】:

这是我正在使用的,它几乎可以完美运行:

演示

代码

public extension View 
    func adaptToKeyboard() -> some View 
        modifier(AdaptToSoftwareKeyboard())
    


public struct AdaptToSoftwareKeyboard: ViewModifier 
    @State var currentHeight: CGFloat = 0

    public func body(content: Content) -> some View 
        content
            .padding(.bottom, currentHeight)
            .edgesIgnoringSafeArea(.bottom)
            .animation(.spring())
            .onAppear(perform: subscribeToKeyboardEvents)
    

    private func subscribeToKeyboardEvents() 
        NotificationCenter.Publisher(
            center: NotificationCenter.default,
            name: UIResponder.keyboardWillShowNotification
        )
            .compactMap  $0.userInfo?["UIKeyboardFrameEndUserInfoKey"] as? CGRect 
            .map  $0.height 
            .subscribe(Subscribers.Assign(object: self, keyPath: \.currentHeight))

        NotificationCenter.Publisher(
            center: NotificationCenter.default,
            name: UIResponder.keyboardWillHideNotification
        )
            .compactMap  _ in CGFloat.zero 
            .subscribe(Subscribers.Assign(object: self, keyPath: \.currentHeight))
    


用法

someView()
    .adaptToKeyboard()

在此处使用演示进行测试:https://github.com/youjinp/SwiftUIKit

【讨论】:

以上是关于Dialog 出现消失动画和位置的主要内容,如果未能解决你的问题,请参考以下文章

dialog中含有editext,dialog消失以后,系统键盘怎么不消失

动画消失时不起作用,但出现时起作用

做幻灯片中如何使一段文字消失的同时出现另一段文字?

单元格消失时动画停止,再次出现时动画停止

使用淡入淡出动画使组框出现和消失

ppt点文字消失但又出新内容怎么做