Swift:启动和停止自定义 class 内的 activity 指标的动画
Swift: starting and stopping the animation of an activity indicator inside a custom class
我想在自定义 class 中放置一个 activity 指示器,这样我就可以从任何视图控制器 start/stop 它。
下面的代码在启动 activity 指标但没有停止时有效,我该怎么做?
static func activityIndicatorFunction(view: UIView, targetVC: UIViewController, animate: Bool) {
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
if animate == false {
activityIndicator.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()
} else {
activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1)
activityIndicator.layer.cornerRadius = 6
activityIndicator.center = targetVC.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
//UIApplication.shared.beginIgnoringInteractionEvents()
}
}
一个启动 activity 指标的例子,如果我想停止它,animate 参数将为 false。
Utils.activityIndicatorFunction(view: view, targetVC: self, animate: true)
我的建议是将它们实现为两个独立的方法,也将它们添加到UIViewController
的扩展中,如下:
UIViewController 扩展:
extension UIViewController {
func showActivityIndicator() {
let activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1)
activityIndicator.layer.cornerRadius = 6
activityIndicator.center = view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = .WhiteLarge
activityIndicator.startAnimating()
//UIApplication.shared.beginIgnoringInteractionEvents()
activityIndicator.tag = 100 // 100 for example
// before adding it, you need to check if it is already has been added:
for subview in view.subviews {
if subview.tag == 100 {
print("already added")
return
}
}
view.addSubview(activityIndicator)
}
func hideActivityIndicator() {
let activityIndicator = view.viewWithTag(100) as? UIActivityIndicatorView
activityIndicator?.stopAnimating()
// I think you forgot to remove it?
activityIndicator?.removeFromSuperview()
//UIApplication.shared.endIgnoringInteractionEvents()
}
}
我假设你总是希望 show/hide 将 activityIndicator
变为 ViewController.view
,如果不是,你可能需要让它成为 [=34] =]指标 UIView
而不是 UIViewController
.
用法:
例如,假设您有两个 IBAction,第一个显示 activity 指标,另一个隐藏它,它们应该像:
@IBAction func show(sender: AnyObject) {
showActivityIndicator()
}
@IBAction func hide(sender: AnyObject) {
hideActivityIndicator()
}
这是协议扩展的完美候选者。我最近自己做了这个。
首先在文件中创建协议,比如ActivityIndicatorPresenter.swift
/// Used for ViewControllers that need to present an activity indicator when loading data.
public protocol ActivityIndicatorPresenter {
/// The activity indicator
var activityIndicator: UIActivityIndicatorView { get }
/// Show the activity indicator in the view
func showActivityIndicator()
/// Hide the activity indicator in the view
func hideActivityIndicator()
}
创建协议扩展(在同一个文件中...或不同的文件)
public extension ActivityIndicatorPresenter where Self: UIViewController {
func showActivityIndicator() {
DispatchQueue.main.async {
self.activityIndicator.activityIndicatorViewStyle = .whiteLarge
self.activityIndicator.frame = CGRect(x: 0, y: 0, width: 80, height: 80) //or whatever size you would like
self.activityIndicator.center = CGPoint(x: self.view.bounds.size.width / 2, y: self.view.bounds.height / 2)
self.view.addSubview(self.activityIndicator)
self.activityIndicator.startAnimating()
}
}
func hideActivityIndicator() {
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
self.activityIndicator.removeFromSuperview()
}
}
}
任何视图控制器都可以遵守协议
class MyViewController: UIViewController, ActivityIndicatorPresenter {
/// Make sure to add the activity indicator
var activityIndicator = UIActivityIndicatorView()
//Suppose you want to load some data from the network in this view controller
override func viewDidLoad() {
super.viewDidLoad()
showActivityIndicator() //Wow you can use this here!!!
getSomeData { data in
//do stuff with data
self.hideActivityIndicator()
}
}
我发现最好只是将 'tag' 设置为 activity 指示器,然后在停止动画时引用它,按照 Ahmad 的建议使用一个函数隐藏和显示一个函数。 Ahmad F 的回答和 Guillermo 的回答似乎也不错。
Show/hide 在我的 Utils.swift 文件中运行:
static func showActivityIndicator(view: UIView, targetVC: UIViewController) {
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1)
activityIndicator.layer.cornerRadius = 6
activityIndicator.center = targetVC.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
activityIndicator.tag = 1
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
UIApplication.shared.beginIgnoringInteractionEvents()
}
static func hideActivityIndicator(view: UIView) {
let activityIndicator = view.viewWithTag(1) as? UIActivityIndicatorView
activityIndicator?.stopAnimating()
activityIndicator?.removeFromSuperview()
UIApplication.shared.endIgnoringInteractionEvents()
}
调用显示函数:
Utils.showActivityIndicator(view: view, targetVC: self)
调用隐藏函数:
Utils.hideActivityIndicator(view: view)
我想在自定义 class 中放置一个 activity 指示器,这样我就可以从任何视图控制器 start/stop 它。
下面的代码在启动 activity 指标但没有停止时有效,我该怎么做?
static func activityIndicatorFunction(view: UIView, targetVC: UIViewController, animate: Bool) {
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
if animate == false {
activityIndicator.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()
} else {
activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1)
activityIndicator.layer.cornerRadius = 6
activityIndicator.center = targetVC.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
//UIApplication.shared.beginIgnoringInteractionEvents()
}
}
一个启动 activity 指标的例子,如果我想停止它,animate 参数将为 false。
Utils.activityIndicatorFunction(view: view, targetVC: self, animate: true)
我的建议是将它们实现为两个独立的方法,也将它们添加到UIViewController
的扩展中,如下:
UIViewController 扩展:
extension UIViewController {
func showActivityIndicator() {
let activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1)
activityIndicator.layer.cornerRadius = 6
activityIndicator.center = view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = .WhiteLarge
activityIndicator.startAnimating()
//UIApplication.shared.beginIgnoringInteractionEvents()
activityIndicator.tag = 100 // 100 for example
// before adding it, you need to check if it is already has been added:
for subview in view.subviews {
if subview.tag == 100 {
print("already added")
return
}
}
view.addSubview(activityIndicator)
}
func hideActivityIndicator() {
let activityIndicator = view.viewWithTag(100) as? UIActivityIndicatorView
activityIndicator?.stopAnimating()
// I think you forgot to remove it?
activityIndicator?.removeFromSuperview()
//UIApplication.shared.endIgnoringInteractionEvents()
}
}
我假设你总是希望 show/hide 将 activityIndicator
变为 ViewController.view
,如果不是,你可能需要让它成为 [=34] =]指标 UIView
而不是 UIViewController
.
用法:
例如,假设您有两个 IBAction,第一个显示 activity 指标,另一个隐藏它,它们应该像:
@IBAction func show(sender: AnyObject) {
showActivityIndicator()
}
@IBAction func hide(sender: AnyObject) {
hideActivityIndicator()
}
这是协议扩展的完美候选者。我最近自己做了这个。
首先在文件中创建协议,比如ActivityIndicatorPresenter.swift
/// Used for ViewControllers that need to present an activity indicator when loading data.
public protocol ActivityIndicatorPresenter {
/// The activity indicator
var activityIndicator: UIActivityIndicatorView { get }
/// Show the activity indicator in the view
func showActivityIndicator()
/// Hide the activity indicator in the view
func hideActivityIndicator()
}
创建协议扩展(在同一个文件中...或不同的文件)
public extension ActivityIndicatorPresenter where Self: UIViewController {
func showActivityIndicator() {
DispatchQueue.main.async {
self.activityIndicator.activityIndicatorViewStyle = .whiteLarge
self.activityIndicator.frame = CGRect(x: 0, y: 0, width: 80, height: 80) //or whatever size you would like
self.activityIndicator.center = CGPoint(x: self.view.bounds.size.width / 2, y: self.view.bounds.height / 2)
self.view.addSubview(self.activityIndicator)
self.activityIndicator.startAnimating()
}
}
func hideActivityIndicator() {
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
self.activityIndicator.removeFromSuperview()
}
}
}
任何视图控制器都可以遵守协议
class MyViewController: UIViewController, ActivityIndicatorPresenter {
/// Make sure to add the activity indicator
var activityIndicator = UIActivityIndicatorView()
//Suppose you want to load some data from the network in this view controller
override func viewDidLoad() {
super.viewDidLoad()
showActivityIndicator() //Wow you can use this here!!!
getSomeData { data in
//do stuff with data
self.hideActivityIndicator()
}
}
我发现最好只是将 'tag' 设置为 activity 指示器,然后在停止动画时引用它,按照 Ahmad 的建议使用一个函数隐藏和显示一个函数。 Ahmad F 的回答和 Guillermo 的回答似乎也不错。
Show/hide 在我的 Utils.swift 文件中运行:
static func showActivityIndicator(view: UIView, targetVC: UIViewController) {
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1)
activityIndicator.layer.cornerRadius = 6
activityIndicator.center = targetVC.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
activityIndicator.tag = 1
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
UIApplication.shared.beginIgnoringInteractionEvents()
}
static func hideActivityIndicator(view: UIView) {
let activityIndicator = view.viewWithTag(1) as? UIActivityIndicatorView
activityIndicator?.stopAnimating()
activityIndicator?.removeFromSuperview()
UIApplication.shared.endIgnoringInteractionEvents()
}
调用显示函数:
Utils.showActivityIndicator(view: view, targetVC: self)
调用隐藏函数:
Utils.hideActivityIndicator(view: view)