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

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

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

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

Q&A

1回答

1658閲覧

objc_getAssociatedObject/objc_setAssociatedObjectにメソッドを介してkey(UnsafeRawPointer)を渡したい

RiteHour

総合スコア7

Swift

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

0グッド

0クリップ

投稿2017/01/19 06:32

編集2017/01/19 08:27

###前提・実現したいこと
ViewControllerで複数のカスタムViewControllerを表示させたい(presentViewみたいな感じで)

不特定多数のViewControllerで表示させたいのでUIWindowを使用して、どこでも呼べるようにしよう

UIWindowを使用して表示する上で、objc_getAssociatedObject/objc_setAssociatedObject周りで

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

使用するkey(UnsafeRawPointer)をメソッドで渡し、
objc_setAssociatedObjectを行うが、
objc_getAssociatedObject時にnilが返却されてしまう

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

class DialogBase: UIViewController { func show(viewController: UIViewController, key: UnsafeRawPointer) { window = UIWindow(frame: UIScreen.main.bounds) window.alpha = 0 window.rootViewController = viewController window.windowLevel = UIWindowLevelNormal window.makeKeyAndVisible() objc_setAssociatedObject(UIApplication.shared, key, window, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) // UIWindowを上にアニメーション window.alpha = 1.0 window.top = UIScreen.main.bounds.height UIView.transition(with: window, duration: 0.3, options: [], animations: { self.window.top = 0 }) { (_) in } } func close(key: UnsafeRawPointer) { // ここでobjectがnilになってしまう guard let window = objc_getAssociatedObject(UIApplication.shared, key) as? UIWindow else { return } // UIWindowを下にアニメーション UIView.transition(with: window, duration: 0.3, options: [], animations: { window.top = UIScreen.main.bounds.height }) { (finished) in window.rootViewController?.view.removeFromSuperview() window.rootViewController = nil objc_setAssociatedObject(UIApplication.shared, key, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) // 一つ前のwindowを表示する let windows = UIApplication.shared.windows guard let nextWindow = windows.last else { return } nextWindow.makeKeyAndVisible() } } } ------------------------------------------------------------------ class CustomDialog: DialogBase { static let getInstance: CustomDialog = CustomDialog() func show() { let viewController = UIStoryboard(name: "CustomDialog", bundle: nil).instantiateInitialViewController() super.show(viewController: viewController!, key: Utility.bridge(obj: self)) } func close() { super.close(key: Utility.bridge(obj: self)) } } ------------------------------------------------------------------ class SampleViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() CustomDialog.getInstance.show() } } ------------------------------------------------------------------ class Utility { static func bridge<T: AnyObject>(obj: T) -> UnsafeMutableRawPointer { return Unmanaged.passRetained(obj).toOpaque() } static func bridge<T: AnyObject>(ptr: UnsafeRawPointer) -> T { return Unmanaged<T>.fromOpaque(ptr).takeRetainedValue() } }

###試したこと

  • Baseクラスにstatic var Keyを記載して、そのKeyをobjc_getAssociatedObjectに&Keyで読み込むと正常に動作することからメソッドを介してKeyを渡すと同一のKeyではなくなってしまう・・・?
  • BaseクラスにviewControllerごとにif文を書いて、それぞれのobjc_getAssociatedObject/objc_setAssociatedObjectを記載したが同様にobjc_getAssociatedObjectでnilが返却されてしまった

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

  • Xcode8.2
  • Swift3
UIViewにExtensionしてます extension UIView { var top : CGFloat{ get{ return self.frame.origin.y } set{ var frame = self.frame frame.origin.y = newValue self.frame = frame } } var bottom : CGFloat{ get{ return frame.origin.y + frame.size.height } set{ var frame = self.frame frame.origin.y = newValue - self.frame.size.height self.frame = frame } } var right : CGFloat{ get{ return self.frame.origin.x + self.frame.size.width } set{ var frame = self.frame frame.origin.x = newValue - self.frame.size.width self.frame = frame } } var left : CGFloat{ get{ return self.frame.origin.x } set{ var frame = self.frame frame.origin.x = newValue self.frame = frame } } }

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

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

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

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

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

guest

回答1

0

keyはclose()の引数を使うんじゃないんでしょうか?

swift

1func close(key: UnsafeRawPointer) { 2 guard let window = objc_getAssociatedObject(UIApplication.shared, key) as? UIWindow else { 3 return 4 } 5 :

投稿2017/01/19 07:41

fuzzball

総合スコア16731

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

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

RiteHour

2017/01/19 08:25

申し訳ありません、記載ミスです! 引数のkeyを使用したのですが、同様にobjc_getAssociatedObjectでnilが返ってきてしまいます
fuzzball

2017/01/19 08:30

show()とclose()のkeyが一致しているかprintして確認して下さい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問