iOSアプリで円形のプログレスバーを作成する方法を解説
iOS開発者にとって、円形のプログレスバー(Circular Progress Bar)の作り方を知っていることは非常に重要です。ダウンロード状況や読み込み中の状態、その他進捗を示す場面のほとんどで使われるため、ほぼすべてのアプリで目にするUI要素と言えるでしょう。
初心者のプログラマーにとっては、円形プログレスバーの実装は難しく感じられ、苦戦することも少なくありません。実装方法はいくつかありますが、この記事ではその中でも最もシンプルで簡単な方法を紹介します。
それでは始めましょう。
Step 1:Xcodeプロジェクトの作成
Xcodeを開き、「Single View Application」を選択して、プロジェクト名を「CircularProgress」とします。
今回作成するのは、パーセンテージを表す3つのボタンと1つの円形プログレスビューを持つアプリです。ボタンをタップすると、対応するパーセンテージに応じてプログレスビューが変化します。
Step 2:カスタムクラスの作成
新しいクラスを作成します。「File」→「New」→「File...」→「Cocoa Touch Class」の順に選択し、UIViewクラスを継承した「CircularProgressView」クラスを作成してください。
Step 3:UIの構築
Storyboard上にUIViewを配置し、そのクラスとして「CircularProgressView」を設定します。さらに3つのボタンを追加し、それぞれ「30%」「60%」「95%」という名前を付けましょう。
次に、ViewController.swiftに3つのボタンすべてに対する@IBActionを作成します。
@IBAction func btn95(_ sender: Any) {
}
@IBAction func btn30(_ sender: Any) {
}
@IBAction func btn60(_ sender: Any) {
}続いて、UIViewに対応する@IBOutletもViewController.swiftに作成します。
@IBOutlet weak var circularProgress: CircularProgressView!
Step 4:レイヤーの定義
CircularProgressView.swift内で、CAShapeLayer型のオブジェクト「progressLyr」と「trackLyr」の2つを作成します。
var progressLyr = CAShapeLayer() var trackLyr = CAShapeLayer()
Step 5:色プロパティとdidSetの実装
progressLyrとtrackLyrの色を設定するためのプロパティと、didSetメソッドを以下のように記述します。
var progressClr = UIColor.white {
didSet {
progressLyr.strokeColor = progressClr.cgColor
}
}
var trackClr = UIColor.white {
didSet {
trackLyr.strokeColor = trackClr.cgColor
}
}ここではprogressLyrとtrackLyrのプロパティを設定しています。
didSetはプロパティオブザーバーの一種で、プロパティの値の変化を監視して反応する仕組みです。プロパティオブザーバーは、新しい値が現在の値と同じであっても、値がセットされるたびに呼び出されます。
Step 6:円形パスの生成
makeCircularPath関数を追加し、以下のコードを記述します。
func makeCircularPath() {
self.backgroundColor = UIColor.clear
self.layer.cornerRadius = self.frame.size.width/2
let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width/2, y: frame.size.height/2), radius: (frame.size.width - 1.5)/2, startAngle: CGFloat(-0.5 * .pi), endAngle: CGFloat(1.5 * .pi), clockwise: true)
trackLyr.path = circlePath.cgPath
trackLyr.fillColor = UIColor.clear.cgColor
trackLyr.strokeColor = trackClr.cgColor
trackLyr.lineWidth = 5.0
trackLyr.strokeEnd = 1.0
layer.addSublayer(trackLyr)
progressLyr.path = circlePath.cgPath
progressLyr.fillColor = UIColor.clear.cgColor
progressLyr.strokeColor = progressClr.cgColor
progressLyr.lineWidth = 10.0
progressLyr.strokeEnd = 0.0
layer.addSublayer(progressLyr)
}この関数では円形のパスを作成し、そのパラメータや動作を定義しています。trackLyr(トラック層)は全体の背景となるリング、progressLyr(プログレス層)は実際の進捗を示すリングです。
Step 7:初期化処理の実装
必要なinit関数を追加します。StoryboardからUIを設計する場合はrequired initを使用し、コードでUIを構築する場合はoverride initを使用します。今回はStoryboardを使うため、required initを採用します。
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
makeCircularPath()
}Step 8:アニメーション機能の追加
次に、プログレスをアニメーション表示するための関数setProgressWithAnimationを作成し、以下のコードを書きます。
func setProgressWithAnimation(duration: TimeInterval, value: Float) {
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 0
animation.toValue = value
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
progressLyr.strokeEnd = CGFloat(value)
progressLyr.add(animation, forKey: "animateprogress")
}CircularProgressView.swiftの完成版コード
以上で完了です。CircularProgressView.swiftの最終的なコードは以下のようになります。
import UIKit
class CircularProgressView: UIView {
var progressLyr = CAShapeLayer()
var trackLyr = CAShapeLayer()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
makeCircularPath()
}
var progressClr = UIColor.white {
didSet {
progressLyr.strokeColor = progressClr.cgColor
}
}
var trackClr = UIColor.white {
didSet {
trackLyr.strokeColor = trackClr.cgColor
}
}
func makeCircularPath() {
self.backgroundColor = UIColor.clear
self.layer.cornerRadius = self.frame.size.width/2
let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width/2, y: frame.size.height/2), radius: (frame.size.width - 1.5)/2, startAngle: CGFloat(-0.5 * .pi), endAngle: CGFloat(1.5 * .pi), clockwise: true)
trackLyr.path = circlePath.cgPath
trackLyr.fillColor = UIColor.clear.cgColor
trackLyr.strokeColor = trackClr.cgColor
trackLyr.lineWidth = 5.0
trackLyr.strokeEnd = 1.0
layer.addSublayer(trackLyr)
progressLyr.path = circlePath.cgPath
progressLyr.fillColor = UIColor.clear.cgColor
progressLyr.strokeColor = progressClr.cgColor
progressLyr.lineWidth = 10.0
progressLyr.strokeEnd = 0.0
layer.addSublayer(progressLyr)
}
func setProgressWithAnimation(duration: TimeInterval, value: Float) {
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 0
animation.toValue = value
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
progressLyr.strokeEnd = CGFloat(value)
progressLyr.add(animation, forKey: "animateprogress")
}
}Step 9:動作確認
ここまでのコードを実行して、問題なく動作するか確認しましょう。ViewController.swiftにはまだ何もコードを追加していないため、UIは表示されますがまだ機能しません。
Step 10:ViewController.swiftへのコード追加
それでは、ViewController.swiftにコードを追加していきましょう。
まずviewDidLoad()に以下の行を記述します。これによりプログレスバーの色が指定されます。
circularProgress.trackClr = UIColor.cyan circularProgress.progressClr = UIColor.purple
次に、ボタンのアクションに以下のコードを追加します。durationはそれぞれ95%、30%、60%に対応させています。
@IBAction func btn95(_ sender: Any) {
circularProgress.setProgressWithAnimation(duration: 1.0, value: 0.95)
}
@IBAction func btn30(_ sender: Any) {
circularProgress.setProgressWithAnimation(duration: 1.0, value: 0.30)
}
@IBAction func btn60(_ sender: Any) {
circularProgress.setProgressWithAnimation(duration: 1.0, value: 0.60)
}ボタンの各関数では、値とdurationを引数としてsetProgressWithAnimationを呼び出しています。
ViewController.swiftの完成版コード
最終的に、ViewController.swiftは以下のようになります。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var circularProgress: CircularProgressView!
override func viewDidLoad() {
super.viewDidLoad()
circularProgress.trackClr = UIColor.cyan
circularProgress.progressClr = UIColor.purple
}
@IBAction func btn95(_ sender: Any) {
circularProgress.setProgressWithAnimation(duration: 1.0, value: 0.95)
}
@IBAction func btn30(_ sender: Any) {
circularProgress.setProgressWithAnimation(duration: 1.0, value: 0.30)
}
@IBAction func btn60(_ sender: Any) {
circularProgress.setProgressWithAnimation(duration: 1.0, value: 0.60)
}
}まとめ
これですべて完了です。アプリを実行して「30%」「60%」「95%」のいずれかのボタンをタップすると、ビューがアニメーションしながら進捗を表示するのが確認できます。
CAShapeLayerとCABasicAnimationを組み合わせることで、複雑な描画処理を書かずとも滑らかな円形プログレスバーを簡単に実装できることが分かりました。ぜひ自分のアプリにも応用してみてください。
-
Tkinterでダウンロードプログレスバーを実装する方法を解説
ファイルのダウンロードや進捗状況の追跡など、外部ソースやファイルとやり取りするアプリケーションを開発する場合、処理の進行状況をユーザーに視覚的に伝えるプログレスバーがあると便利です。Tkinterでプログレスバーを作成するには、tkinter.ttkパッケージに含まれるProgressbarモジュールを使用します。まずProgressbarオブジェクトをインスタンス化し、向き(orientation)をHORIZONTAL(水平方向)に設定します。その後、プログレスバーの値を増加させながら継続的に更新する関数を定義することで、ダウンロードの進捗を表現できます。サンプルコード以下の例では、プログ
-
iPhone・iPadでショートカットを作成する方法|自動化で毎日の作業を時短しよう
日々の生活の中で、少しでも時間を節約したいと考えている人は多いはず。だからこそ、日常生活に「自動化」を取り入れることを強くおすすめします。 自動化こそ、テクノロジーがもたらす最大のメリットのひとつです。本来なら3回のタップが必要だった操作を、わずか1回で済ませられるようにしてくれます。これを活用しない手はありませんよね。 iOSデバイスでは、この自動化機能が「ショートカット」と呼ばれています。すでに多くの開発者たちが、日常的なタスクを効率化する優れたショートカットを公開しています。さらに嬉しいことに、作成したショートカットはiCloud経由で他のiOSデバイスとも同期できるのです。