質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

3367閲覧

swift3でアナログ時計の回転軸が分からない

keys

総合スコア215

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

1クリップ

投稿2017/05/21 08:27

正しい質問の仕方が出来てないかもしれませんがご了承ください。アナログ時計を実装しているのですが、秒針がうまく回転しましせん。時間通りに回転はするのですが、ブーメランみたいにくるくる回ってるだけです。

イメージ説明

分からないこと

画像を正確に回転させるロジックがよくわかっていません。例えば、UIViewの座標の原点が左上だとしたら、左上から中心になるように画像を表示させ、そのまま回転を加えても、同じようなことになります。

どのような画像を、どのよう座標の原点で回せばいいのでしょうか。考え方をアドバイスいただけますか。まあ、QuartzCore、CALayer、CGAffineTransform、CATransform3D、CAAnimationらへんの知識を積もうと思っています。

実装

赤い丸と秒針は別々の画像です。秒針の一番下を軸として、赤い丸の部分から離脱することなく正確に回したいです。上記の画像の実装のロジックは下記のように書いています。

Timer を使って1秒ごとに処理を実行します。

swift

1func update(tm: Timer) { 2 //アナログ時計実装のための関数

swift

1let date = Date()
let calendar = Calendar.current
let sDeg = seconds * (360 / 60)
let seconds = calendar.component(.second, from: date)

回転実行

swift

1secondsImage.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI * Double(sDeg) / 180.0)) 2 3//下記のような警告が出てます 4 5//'M_PI' is deprecated: Please use 'Double.pi' or '.pi' to get the value of correct type and avoid casting.

全ソース

swift

1let xPosition = TopMenu.frame.origin.x 2 let yPosition = TopMenu.frame.origin.y - CGFloat(isClosed) 3 let height = TopMenu.frame.size.height 4 let width = TopMenu.frame.size.width 5 UIView.animate(withDuration: 1.0, animations: { 6 self.TopMenu.frame = CGRect(x:xPosition, y:yPosition, width:width, height:height) 7 }) 8 } 9 func update(tm: Timer) { 10 //アナログ時計実装のための関数 11 let date = Date() 12 let calendar = Calendar.current 13 let hour = calendar.component(.hour, from: date) 14 let minutes = calendar.component(.minute, from: date) 15 let seconds = calendar.component(.second, from: date) 16 17 let hDeg = (hour % 12) * (360 / 12); 18 let mDeg = minutes * (360 / 60); 19 let sDeg = seconds * (360 / 60) 20 print(hDeg) 21 print(mDeg) 22 print(sDeg) 23 24 25 secondsImage.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI * Double(sDeg) / 180.0)) 26 27 //= CGAffineTransform(rotationAngle: CGFloat(M_PI * Double(sDeg) / 180.0)); 28 29 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2017/05/22 00:18

秒針の画像はどのような画像でしょうか?例えば、2x100のような縦長の画像でしょうか?
guest

回答2

0

ベストアンサー

手抜き

簡単なのは下のような画像を用意することです。
秒針

赤が秒針で、緑が回転の中心になります。
黒い外枠は分かりやすいように付けているだけで、実際には下半分は透明です。

下記のような警告が出てます
'M_PI' is deprecated: Please use 'Double.pi' or '.pi' to get the value of correct type and avoid casting.

書いてある通りDouble.piを使って下さい。

真面目に

変換するの面倒なのでSwift2.3です。

swift

1let t1 = CGAffineTransformMakeTranslation(0, -secondsImage.bounds.height/2) //起点ずらす 2let t2 = CGAffineTransformMakeRotation(CGFloat(M_PI * Double(sDeg) / 180.0)) //回転 3secondsImage.transform = CGAffineTransformConcat(t1, t2) //合体!

絵はこんな感じ。
秒針

honamiさんの回答をコード化

起点をずらす。
viewDidLoad()などで一回代入しておけばいいです。

swift

1secondsImage.layer.anchorPoint = CGPoint(x: 0, y: +1.0)

回転部分のコードは変更なし。

swift

1secondsImage.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi * Double(sDeg) / 180.0))

絵は「真面目に」と同じです。

投稿2017/05/22 00:47

編集2017/05/22 05:25
fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keys

2017/05/22 01:48

ご丁寧にご回答ありがとうございます。おっしゃる通り考えてみれば、画像の中心に針の先端部がくるようにしないとブーメランみたいに回るのは普通に考えればわかることでした。非常に助かりました、ありがとうございます。
honami

2017/05/22 06:24

わざわざコード書いてもらって申し訳ない!助かります。
guest

0

CALayer anchorpointあたりのキーワードが参考になるかもしれません。
UIViewのアニメーション基準点を変更することができます。

投稿2017/05/22 00:56

honami

総合スコア308

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keys

2017/05/22 01:49

ご回答ありがとうございました。CALayerやanchorpointの知識足りてないので勉強させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問