在 Window 的子视图中添加子视图
Adding a subview inside a view which is a subview of Window
我正在尝试使用 Lottie
动画创建自定义 IndicatorView
。
我已经在 UIApplication.shared.keyWindow?
中添加了视图并且它工作正常。
当我尝试在 IndicatorView
中添加另一个子视图时出现问题。
当我尝试在 loadingAnimation
上添加约束时,代码在 setupLoadingView()
中崩溃。
UPDATE: Thanks to @Raghav7890. There was a silly mistake which has been solved now. I have
updated the answer for anyone who wants to create a custom Indicator
View using Lottie Animations. Have fun.
代码如下:
import Foundation
import UIKit
import Lottie
class IndicatorView : UIView {
static let shared = IndicatorView()
var loadingAnimation : AnimationView = {
let lottieView = AnimationView()
lottieView.translatesAutoresizingMaskIntoConstraints = false
lottieView.layer.masksToBounds = true
return lottieView
}()
override init(frame: CGRect) {
super.init(frame: frame)
translatesAutoresizingMaskIntoConstraints = false
setupLoadingView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func show() {
self.alpha = 0
UIView.animate(withDuration: 0.5, animations: {
self.isHidden = false
self.alpha = 1
}, completion: nil)
applyLottieAnimation()
}
public func hide() {
removeLoadingView()
}
func applyLottieAnimation() {
let animationToShow = Animation.named("loading")
loadingAnimation.animation = animationToShow
loadingAnimation.animationSpeed = 1.0
loadingAnimation.loopMode = .loop
loadingAnimation.contentMode = .scaleAspectFill
loadingAnimation.play()
}
private func setupLoadingView() {
UIApplication.shared.keyWindow?.addSubview(self)
self.backgroundColor = UIColor.darkGray.withAlphaComponent(0.5)
guard let activeWindow = UIApplication.shared.keyWindow?.layoutMarginsGuide else {return}
self.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.size.height + 100).isActive = true
self.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.size.width).isActive = true
self.centerXAnchor.constraint(equalTo: activeWindow.centerXAnchor).isActive = true
self.centerYAnchor.constraint(equalTo: activeWindow.centerYAnchor).isActive = true
self.addSubview(loadingAnimation)
loadingAnimation.heightAnchor.constraint(equalToConstant: 100).isActive = true
loadingAnimation.widthAnchor.constraint(equalToConstant: 100).isActive = true
loadingAnimation.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
loadingAnimation.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
loadingAnimation.backgroundColor = UIColor(red: 48/255, green: 72/255, blue: 96/255, alpha: 1.0)
loadingAnimation.applyCornerRadius()
loadingAnimation.clipsToBounds = true
self.setNeedsLayout()
self.reloadInputViews()
}
func removeLoadingView() {
self.alpha = 1
UIView.animate(withDuration: 0.5, animations: {
self.alpha = 0
self.loadingAnimation.stop()
}, completion: { _ in
self.isHidden = true
})
}
}
尝试像这样使用你的属性
var loadingAnimation : AnimationView = {
let lottieView = AnimationView()
lottieView.translatesAutoresizingMaskIntoConstraints = false
// lottieView.contentMode = .scaleAspectFit
lottieView.layer.masksToBounds = true
return lottieView
}()
var loadingLabel : UILabel = {
let label = UILabel()
label.text = loadingText
label.textColor = .white
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont(name: "SegoeUI", size: 12)
return label
}()
由于您的方法会在您每次访问时生成一个新对象
我正在尝试使用 Lottie
动画创建自定义 IndicatorView
。
我已经在 UIApplication.shared.keyWindow?
中添加了视图并且它工作正常。
当我尝试在 IndicatorView
中添加另一个子视图时出现问题。
当我尝试在 loadingAnimation
上添加约束时,代码在 setupLoadingView()
中崩溃。
UPDATE: Thanks to @Raghav7890. There was a silly mistake which has been solved now. I have updated the answer for anyone who wants to create a custom Indicator View using Lottie Animations. Have fun.
代码如下:
import Foundation
import UIKit
import Lottie
class IndicatorView : UIView {
static let shared = IndicatorView()
var loadingAnimation : AnimationView = {
let lottieView = AnimationView()
lottieView.translatesAutoresizingMaskIntoConstraints = false
lottieView.layer.masksToBounds = true
return lottieView
}()
override init(frame: CGRect) {
super.init(frame: frame)
translatesAutoresizingMaskIntoConstraints = false
setupLoadingView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func show() {
self.alpha = 0
UIView.animate(withDuration: 0.5, animations: {
self.isHidden = false
self.alpha = 1
}, completion: nil)
applyLottieAnimation()
}
public func hide() {
removeLoadingView()
}
func applyLottieAnimation() {
let animationToShow = Animation.named("loading")
loadingAnimation.animation = animationToShow
loadingAnimation.animationSpeed = 1.0
loadingAnimation.loopMode = .loop
loadingAnimation.contentMode = .scaleAspectFill
loadingAnimation.play()
}
private func setupLoadingView() {
UIApplication.shared.keyWindow?.addSubview(self)
self.backgroundColor = UIColor.darkGray.withAlphaComponent(0.5)
guard let activeWindow = UIApplication.shared.keyWindow?.layoutMarginsGuide else {return}
self.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.size.height + 100).isActive = true
self.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.size.width).isActive = true
self.centerXAnchor.constraint(equalTo: activeWindow.centerXAnchor).isActive = true
self.centerYAnchor.constraint(equalTo: activeWindow.centerYAnchor).isActive = true
self.addSubview(loadingAnimation)
loadingAnimation.heightAnchor.constraint(equalToConstant: 100).isActive = true
loadingAnimation.widthAnchor.constraint(equalToConstant: 100).isActive = true
loadingAnimation.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
loadingAnimation.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
loadingAnimation.backgroundColor = UIColor(red: 48/255, green: 72/255, blue: 96/255, alpha: 1.0)
loadingAnimation.applyCornerRadius()
loadingAnimation.clipsToBounds = true
self.setNeedsLayout()
self.reloadInputViews()
}
func removeLoadingView() {
self.alpha = 1
UIView.animate(withDuration: 0.5, animations: {
self.alpha = 0
self.loadingAnimation.stop()
}, completion: { _ in
self.isHidden = true
})
}
}
尝试像这样使用你的属性
var loadingAnimation : AnimationView = {
let lottieView = AnimationView()
lottieView.translatesAutoresizingMaskIntoConstraints = false
// lottieView.contentMode = .scaleAspectFit
lottieView.layer.masksToBounds = true
return lottieView
}()
var loadingLabel : UILabel = {
let label = UILabel()
label.text = loadingText
label.textColor = .white
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont(name: "SegoeUI", size: 12)
return label
}()
由于您的方法会在您每次访问时生成一个新对象