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

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

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

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

2回答

2762閲覧

他クラスからViewControllerのviewDidLoad内のコードを書き換える方法

mujika

総合スコア13

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2016/09/07 13:27

編集2016/09/10 12:45

始めましてiPhoneアプリ制作しているものです

###前提・実現したいこと

通常時はスクロールをONにして TestDrawクラス内にあるarcとinoパラメーターをタッチした時にスクロールを止めたい

###アプリ画面
アプリイメージ

###発生している問題・エラーメッセージ

Iphoneシミュレーターを起動してarcを触ると self.tou.isScrollEnabled = isScrollEnableの所にエラーがでて落ちる (fatal error: unexpectedly found nil while unwrapping an Optional value)
エラー画面

viewDidLoad内の情報を他クラスから変更する方法はないでしょうか?ご回答いただけるとありがたいです

###該当のソースコード

swift

1import UIKit 2import CoreGraphics 3 4class ViewController: UIViewController { 5 6 7 @IBOutlet weak var tou: UIScrollView! 8 var isScrollEnable = true { 9 didSet { 10 viewDidLoad() 11 } 12 } 13 14 15 override func viewDidLoad() { 16 super.viewDidLoad() 17 18 self.tou.isScrollEnabled = isScrollEnable /*ここを変更したいですがエラーが出ます(fatal error: unexpectedly found nil while unwrapping an Optional value)*/ 19 //スクロール画面の設定 20 self.tou.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height) 21 self.tou.contentSize = CGSize(width: self.view.frame.size.width, height: 900) 22 self.tou.showsVerticalScrollIndicator = false 23 24 //パラメーターボタンの設置 25 let testDraw = TestDraw(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 900 )) 26 testDraw.backgroundColor = UIColor.clear() 27 28 self.tou.addSubview(testDraw) 29 self.view.addSubview(self.tou) 30 31 } 32 33 override func didReceiveMemoryWarning() { 34 super.didReceiveMemoryWarning() 35 // Dispose of any resources that can be recreated. 36 } 37 38 39} 40 41

swift

1import UIKit 2 3class TestDraw: UIView { 4 5 //パラメーターボタン 6 var parameterArc:UIBezierPath! 7 var parameterIno:UIBezierPath! 8 9 10 var radian:CGFloat = -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2) 11 var touchPoint:CGPoint! 12 13 14 //ボタン内をタッチするとパラメーターが動く 15 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 16 17 if let touch = touches.first as UITouch? { 18 self.touchPoint = touch.location(in: self) 19 20 21 22 if parameterArc.contains(touchPoint!) { 23 var viewcon = ViewController() 24 viewcon.isScrollEnable = false //ここでタッチした時にスクロールを止めたいです! 25 26 //タッチした位置に合わせてパラメーターが変化 27 self.radian = -atan2(100 - touchPoint.x, 350 - touchPoint.y) - CGFloat((M_PI)/2) 28 29 if self.radian >= CGFloat((M_PI)*4/5 - (M_PI)/2) { 30 self.radian = CGFloat((M_PI)*4/5 - (M_PI)/2) 31 } else if self.radian <= -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2) { 32 self.radian = -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2) 33 } 34 35 } 36 37 self.setNeedsDisplay() 38 39 } 40 } 41 42 //タッチ後動かしてもパラメーターを変化させる 43 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 44 45 46 if let touch = touches.first as UITouch? { 47 self.touchPoint = touch.location(in: self) 48 49 if parameterArc.contains(touchPoint!) { 50 51 //パラメータの変化 52 self.radian = -atan2(100 - touchPoint.x, 350 - touchPoint.y) - CGFloat((M_PI)/2) 53 54 if self.radian >= CGFloat((M_PI)*4/5 - (M_PI)/2) { 55 self.radian = CGFloat((M_PI)*4/5 - (M_PI)/2) 56 } else if self.radian <= -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2) { 57 self.radian = -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2) 58 } 59 } 60 61 self.setNeedsDisplay() 62 } 63 64 } 65 66 67 //パラメーターの設定、設置 68 override func draw(_ rect: CGRect){ 69 70 self.parameterIno = UIBezierPath(arcCenter: CGPoint(x:120, y:350), radius: 40,startAngle: -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2), endAngle: CGFloat((M_PI)*4/5 - (M_PI)/2), clockwise: true) 71 72 let arcColor = UIColor(red: 0, green: 0.5, blue: 1, alpha: 0.8) 73 arcColor.setStroke() 74 parameterArc.lineWidth = 4 75 parameterArc.lineCapStyle = CGLineCap.round 76 parameterIno.stroke() 77 78 79 self.parameterIno = UIBezierPath(arcCenter: CGPoint(x:120, y:350), radius: 40,startAngle: -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2), endAngle: CGFloat(radian) , clockwise: true) 80 81 let inoColor = UIColor(red: 0, green: 0.2, blue: 0.5, alpha: 1) 82 inoColor.setStroke() 83 parameterIno.lineWidth = 4.4 84 parameterIno.lineCapStyle = CGLineCap.round 85 parameterIno.stroke() 86 87 } 88 89}

##補足情報(言語/FW/ツール等のバージョンなど)
xcode8 beta
swift3.0

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

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

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

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

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

mujika

2016/09/10 12:04

ご指摘ありがとうございました。質問改善してみました宜しくお願いします。
guest

回答2

0

Swiftの本を読み終わり、初めてアプリの作りだった為か30時間ほどかかって、かなり色々試し勉強になりました

アプリ画面
アプリ画面

・今回の解決ポイント

1、CircleParameterクラス内のtouchesBegan内からViewController内のviewDidLoad内のスクロールを止めようとしていたのが間違いでViewController内のtouchesBeganからアプローチした事
2、UIScrollView上ではタッチが親viewに伝わらないので各子viewでoverride func toucheaBegan内にsuperview?.touchesBegan(touches, with: event)を設置して親viewに伝える必要がある事

・よくわからない事

(touch as? UITouch as UITouch?)のキャスト?as asがどうもわかりませんでしたがアプリ開発のスピード重視なのでとりあえず今回は置いておく

・不満点

実際はtouchesCanceledも設置したがキャンセル検知がイマイチなので今後なんとかしたい

以下コード

swift

1import UIKit 2import CoreGraphics 3 4class ViewController: UIViewController { 5 6 //円弧ボタンを宣言 7 var arcSet:CircleParameter! 8 //UIScrollViewクラスの宣言 9 var scrView = ScrollBack() 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 14 //ScrollViewのサイズ 15 self.scrView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height) 16 //スクロールする中身のサイズ 17 self.scrView.contentSize = CGSize(width: self.view.frame.size.width, height: 900) 18 //trueでスクロールする 19 self.scrView.isScrollEnabled = true 20 21 22 //円弧ボタンのviewサイズ、バックカラー、角丸め設定 23 arcSet = CircleParameter(frame: CGRect(x: 60, y: 80, width: 84, height: 84 )) 24 arcSet.backgroundColor = UIColor.clear 25 arcSet.layer.cornerRadius = 42 26 //viewの丸める許可 27 arcSet.clipsToBounds = true 28 29 30 self.view.addSubview(scrView) 31 self.scrView.addSubview(arcSet) 32 33 } 34 35 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 36 37 //タッチされたのが円弧ボタンであればスクロールを止める 38 for touch: AnyObject in touches { 39 //ここはなぜこうなっているのか理解できないけどとりあえず動いてるので今回はOKとしてます 40 let t: UITouch = (touch as? UITouch as UITouch?)! 41 42 if t.view == self.arcSet { 43 //falseでスクロール停止 44 self.scrView.isScrollEnabled = false 45 } 46 } 47 48 } 49 50 override func didReceiveMemoryWarning() { 51 super.didReceiveMemoryWarning() 52 // Dispose of any resources that can be recreated. 53 } 54 55 56} 57

swift

1import UIKit 2 3class ScrollBack: UIScrollView { 4 5 6 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 7 8 //親Viewにタッチを伝える 9 superview?.touchesBegan(touches, with: event) 10 11 12 } 13} 14

swift

1class CircleParameter: UIView { 2 3 //ベジェ曲線を宣言 4 var arc:UIBezierPath! 5 6 7 //円弧ボタンを設置 8 override func draw(_ rect: CGRect) { 9 10 //ボタンの形(円弧)を設定 11 arc = UIBezierPath(arcCenter: CGPoint(x:42, y:42), radius: 40, startAngle: -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2), endAngle:CGFloat ((M_PI)*4/5 - (M_PI)/2), clockwise: true) 12 13 //色、ライン幅、円弧の端の丸みを設定 14 let arcColor = UIColor(red: 1, green: 0.2, blue: 0.5, alpha: 1) 15 arcColor.setStroke() 16 arc.lineWidth = 4 17 arc.lineCapStyle = CGLineCap.round 18 arc.stroke() 19 20 } 21 22 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 23 24 //親Viewにタッチを伝える 25 superview?.touchesBegan(touches, with: event) 26 27 28 } 29 30}

投稿2016/09/28 13:58

mujika

総合スコア13

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

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

0

ベストアンサー

他クラスから

と言うのは遷移前画面?、遷移先画面?、TabBarControllerの他のタブ?いろいろありますが前画面からでしたら、遷移前にプロパティに値を設定すれば良いのではないでしょうか?

swift

1import UIKit 2import CoreGraphics 3 4class ViewController: UIViewController { 5 6 @IBOutlet weak var tou: UIScrollView! 7 var isScrollEnable = false 8 9 override func viewDidLoad() { 10 super.viewDidLoad() 11 12 self.tou.isScrollEnabled = isScrollEnable 13 // ・・・・ 14 } 15}

投稿2016/09/08 00:27

_Kentarou

総合スコア8490

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

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

mujika

2016/09/08 11:41

ご回答ありがとうございます。 遷移せずに同じ画面内に[UIViewでアニメーションするパラメータを作っており(これが他クラスです)]それをタッチするとスクロールが止まるという感じです。 _Kentarouさんに教えていただいた方法で試してみたんですがViewControllerのライフサイクルのせいなのか?色々試してみましたがisScrollEnable の更新が画面に反映されませんでした。 お手数ですが解決方法あればご教授いただけるとありがたいです。
_Kentarou

2016/09/08 15:20

[UIViewでアニメーションするパラメータを作っており(これが他クラスです)]それをタッチすると 上記の部分のコードも回答に追記願いますか? タッチしたところでtou.isScrollEnabledの値を書き換えるだけですが、Viewのクラスとの関係がわからないのでどの様に呼び出したらよいか決めかねます。
mujika

2016/09/10 12:45 編集

先ほどのUIViewでアニメーションするパラメータを作っておりパラメーターを触っている間はスクロールしないようにしたいです。見にくい感じだったので質問の方にもコードあげてみましたよろしくお願いいたします。 import UIKit class TestDraw: UIView { //パラメーターボタン var parameterArc:UIBezierPath! var parameterIno:UIBezierPath! var radian:CGFloat = -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2) var touchPoint:CGPoint! //ボタン内をタッチするとパラメーターが動く override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first as UITouch? { self.touchPoint = touch.location(in: self) if parameterArc.contains(touchPoint!) { var viewcon = ViewController() viewcon.isScrollEnable = false //ここでタッチした時にスクロールを止めたいです! //タッチした位置に合わせてパラメーターが変化 self.radian = -atan2(100 - touchPoint.x, 350 - touchPoint.y) - CGFloat((M_PI)/2) if self.radian >= CGFloat((M_PI)*4/5 - (M_PI)/2) { self.radian = CGFloat((M_PI)*4/5 - (M_PI)/2) } else if self.radian <= -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2) { self.radian = -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2) } } self.setNeedsDisplay() } } //タッチ後動かしてもパラメーターを変化させる override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first as UITouch? { self.touchPoint = touch.location(in: self) if parameterArc.contains(touchPoint!) { //パラメータの変化 self.radian = -atan2(100 - touchPoint.x, 350 - touchPoint.y) - CGFloat((M_PI)/2) if self.radian >= CGFloat((M_PI)*4/5 - (M_PI)/2) { self.radian = CGFloat((M_PI)*4/5 - (M_PI)/2) } else if self.radian <= -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2) { self.radian = -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2) } } self.setNeedsDisplay() } } //パラメーターの設定、設置 override func draw(_ rect: CGRect){ self.parameterIno = UIBezierPath(arcCenter: CGPoint(x:120, y:350), radius: 40,startAngle: -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2), endAngle: CGFloat((M_PI)*4/5 - (M_PI)/2), clockwise: true) let arcColor = UIColor(red: 0, green: 0.5, blue: 1, alpha: 0.8) arcColor.setStroke() parameterArc.lineWidth = 4 parameterArc.lineCapStyle = CGLineCap.round parameterIno.stroke() self.parameterIno = UIBezierPath(arcCenter: CGPoint(x:120, y:350), radius: 40,startAngle: -1 * CGFloat ((M_PI)*4/5 + (M_PI)/2), endAngle: CGFloat(radian) , clockwise: true) let inoColor = UIColor(red: 0, green: 0.2, blue: 0.5, alpha: 1) inoColor.setStroke() parameterIno.lineWidth = 4.4 parameterIno.lineCapStyle = CGLineCap.round parameterIno.stroke() } }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問