簡體   English   中英

如何為 iOS 中的暗模式更改設置動畫?

[英]How to animate dark mode change in iOS?

用戶可以在應用設置的一個部分切換主題,如下所示。

這是通過更改window.overrideUserInterfaceStyle來完成的。

雖然它按預期工作,但更改根本沒有 animation。 與 iOS 設置應用程序中的平滑更改相反,整個應用程序立即進入所選樣式。

只需將作業放在completion UIView.animate(withDuration duration: TimeInterval, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil)的完成中即可。

應用設置

有一種簡單的方法可以通過動畫更改應用程序暗模式主題

if let window = UIApplication.shared.keyWindow {
    UIView.transition (with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
        window.overrideUserInterfaceStyle = .dark //.light or .unspecified
    }, completion: nil)
}

您可以執行以下操作:

var toggleVar = true

@IBAction func buttonDidTap(_ sender: UIButton) {
    
    UIView.animate(withDuration: 0.5, animations: {
        self.overrideUserInterfaceStyle = self.toggleVar ? .dark : .light
        self.view.backgroundColor = .systemBackground
    }) { (_) in
        //set overrideUserInterfaceStyle app wide
        UIApplication.shared.windows.first?.overrideUserInterfaceStyle = self.overrideUserInterfaceStyle
        self.toggleVar.toggle()
    }
}

所以為了動畫背景變化,你需要動畫self.view.backgroundColor = .systemBackground 在完成處理程序中,您可以為整個應用程序設置新的overrideUserInterfaceStyle ...

我有同樣的問題。 在使用UIView/UIWindow.animate/transition和動畫選項嘗試無果之后,我解決了以下問題:

  • 捕獲整個屏幕
  • 使用捕獲的圖像添加全屏 UIImageView
  • 在后台切換用戶界面樣式(不設置動畫)
  • 淡出 UIImageView

假設您還在 UINavigationController 中使用 UITableViewController,例如:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // Disable all checkmarks
    tableView.visibleCells.forEach { (cell) in
        cell.accessoryType = .none
    }
    
    // Set checkmark
    let cell = tableView.cellForRow(at: indexPath)
    cell?.accessoryType = .checkmark
    
    // Capture and add screenshot of current screen
    let imageView = UIImageView()
    imageView.image = UIApplication.shared.makeSnapshot()
    imageView.addTo(self.navigationController!.view).snp.makeConstraints { (maker) in
        maker.edges.equalToSuperview()
    }
    
    // Set new dark mode setting and fade out screenshot
    UIView.animate(withDuration: 0.5, animations: {
        // Important to set it within the animations closure, so that the status bar will animate
        UIApplication.shared.windows.first?.overrideUserInterfaceStyle = .dark
        imageView.alpha = 0
    }) { (_) in
        imageView.removeFromSuperview()
    }
    
    // Deselect row
    tableView.deselectRow(at: indexPath, animated: true)
}

筆記:

  • makeSnapshot()方法來自這篇文章: https : makeSnapshot()
  • 我使用SnapKit添加/布局視圖,因此您可能需要為您的項目相應地更改該行
  • .dark更改為項目的正確動態值

結果:

在設備本身上,對我來說甚至比系統的變化動畫還要流暢!

我使用 Xamarin,對我來說,解決方案是:

UIView TempView = Window.SnapshotView(true);    

Window.Add(TempView);

Window.OverrideUserInterfaceStyle = UIUserInterfaceStyle.Light;

UIView.Animate(0.5,
() => { 
    TempView.Alpha = 0;
},
() => {
    TempView.RemoveFromSuperview();
    TempView.Dispose();
});

Swift 5

@objc func changeStyleHandler() {
    
    guard let window = UIApplication.shared.windows.first else { return }
    
    let newInterfaceStyle: UIUserInterfaceStyle = (traitCollection.userInterfaceStyle == .dark) ? .light : .dark
    
    UIView.transition (with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
        window.overrideUserInterfaceStyle = newInterfaceStyle
    }, completion: nil)
    
}
        UIView.transition (with: view, duration: 0.3, options: .transitionCrossDissolve, animations: {
            self.view.overrideUserInterfaceStyle = .dark //.light or .unspecified
        }, completion: nil)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM