画像を保存したり削除したりするときに待ち時間が発生してしまうのでIndicatorを導入
よくみるクルクルするやつです。
UIActivityIndicatorの設置方法は超簡単。
var myIndicator = UIActivityIndicatorView()
myIndicator.frame = CGRectMake(0,0,150,150)
myIndicator.center = self.view.center
//アニメーションが止まった時にindecatorを隠すかどうか
myIndicator.hidesWhenStopped = false
myIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.White
myIndicator.startAnimating()
self.view.addSubview(myIndicator)
これだけで設置できちゃいます。
しかしIndicatorは常に表示しておくものでもありません。OnOffが必要なものです。
私はこれをメソッド化して必要なときに呼び出すようにしました。
Indicatorと「削除中」ラベルの表示を1つのメソッドに
var myIndicator:UIActivityIndicatorView!
func Indicator(){
myIndicator = UIActivityIndicatorView()
myIndicator.frame = CGRectMake(0,0,150,150)
myIndicator.backgroundColor = UIColor(red:0,green:0,blue:0,alpha:0.5)
myIndicator.layer.cornerRadius = 20.0
myIndicator.center = self.view.center
myIndicator.hidesWhenStopped = false
myIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.White
myIndicator.startAnimating()
self.view.addSubview(myIndicator)
let label = UILabel()
label.frame = CGRectMake(0,0,150,30)
label.layer.position = CGPoint(x:myIndicator.frame.width / 2.0 , y:myIndicator.frame.height / 2.0 + 50.0)
label.text = "削除中"
label.textAlignment = NSTextAlignment.Center
label.font = UIFont.systemFontOfSize(12)
label.textColor = UIColor.whiteColor()
myIndicator.addSubview(label)
}
使用するときは
Indicatorの表示 → 削除処理 → Indicatorを非表示(removeSuperviewで取り除く)
の順で使用しました。
Indicatorが表示されない・・・?
ここで適当にボタンを用意しておきます
let btn = UIButton()
btn.frame = CGRectMake(100,100,50,50)
btn.addTarget(self,action:"btnTapped:",forControlEvents:.TouchUpInside)
self.view.addSubview(btn)
それでこのボタンを押すとIndicatorを表示して画像の削除をする、という処理を書いていきます。
func btnTapped(sender:UIButton){
Indicator()
trash()
}
trashメソッドに削除処理を書いていますがそこは割愛
これだと何故かIndicatorが表示されません。。。。trashに待ち時間が発生するから〜なのだと思いますが。
別のところで同様に使用してみたら動いたり動かなかったり・・・ムムム
対処法
待ち時間のある処理を別スレッドで行うことで解決(こちらは
func btnTapped(sender:UIButton){
Indicator()
self.performSelector("TrashProcessDuringIndicator", withObject: nil, afterDelay: 0.1)
}
func TrashProcessDuringIndicator(){
//待ち時間のある処理をここで行う
trash()
}
performSelector:withObject:afterDelayを使用することで解決〜
trash(){
//削除処理を書いています
~~~~
myIndicator.removeFromSuperview()
}
削除処理が完了したらremoveFromSuperviewでindicatorを取り除いています。
performSelectorよりdispatch_afterを使った方が良い?!
さてここまで書いておいてperformSelector系はメモリ管理で危うい所があるらしいです。
そしてperformSelectorの代わりに
func btnTapped(sender:UIButton){
Indicator()
//performSelectorは消しておきまよう
//self.performSelector("TrashProcessDuringIndicator", withObject: nil, afterDelay: 0.1)
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
self.TrashProcessDuringIndicator()
}
}
func TrashProcessDuringIndicator(){
//待ち時間のある処理をここで行う
trash()
}
こんな感じになりました。
イマイチ使い方が分かっていない所もありますが・・・
何故遅延処理をしたら良いのか〜とかもちゃんと勉強しておきます(;;)
参考リンク
Additional Notes追記
とりあえずSwift4で使ってみた
ウーーーーン。趣旨と変わるけれど一応ちょっとだけ使ってみた。
import UIKit
class SecondViewController: UIViewController {
var indicator:UIActivityIndicatorView!
var count = 5
override func viewDidLoad() {
super.viewDidLoad()
let width = self.view.frame.width
let height = self.view.frame.height
indicator = UIActivityIndicatorView(frame: CGRect(x:0,y:0,width:50,height:50))
indicator.center = CGPoint(x:width / 2,y:height / 2)
indicator.hidesWhenStopped = true
indicator.backgroundColor = UIColor.blue
self.view.addSubview(indicator)
indicator.startAnimating()
//重い処理
let timer = Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(self.timerAction(sender:)),
userInfo: nil,
repeats: true)
timer.fire()
}
@objc func timerAction(sender:Timer) {
count -= 1
if count == 0 {
//indicatorを隠す
self.indicator.stopAnimating()
sender.invalidate()
}
}
}
タイマー動かして5秒間表示して、0になったらインジケータを隠す感じ。
前までhidesWhenStoppedをアニメーションが終わったら隠すじゃなくて、隠れたらアニメーションが終わるみたいなおかしなことが書かれていたので修正しました。
最近でもindicatorはあんまり得意ではないです。 非同期処理と組み合わせて使ってると表示されないってのは最近でもあった気がするけれど、とりあえずまた再現したら追記することにします。
今回はこれで失礼します。
コメントはありません。
現在コメントフォームは工事中です。