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

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

ただいまの
回答率

90.76%

  • Swift

    6682questions

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

  • iOS

    3786questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

[Swift4] 別のクラスから、reloadメソッド呼び出したい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 385

teshiya

score 2

Main, SubのViewControllerが2つあり、MainにおいてWebView(UIWebView)を利用しています。
やりたいこととしては、Sub側のボタンを押したら、MainのWebViewがリロードされるようにしたいです。

class Main: UIWebViewController, UIWebViewDelegate {
    @IBOutlet weak var webView: UIWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.webView.delegate = self
    }
:
:
    func reloadPage() {
        self.webView.reload()
    }
:
:
}
class Sub: UIWebViewController {
:
:
    @IBAction func reload(_ sender: Any) {
        // ここでMainのreloadPage()を呼びたい
  }

Sub側で、Mainをインスタンス化してしまうと、reloadPage()でwebViewがnilとなってしまい実行時にエラーとなってしまいます。
reloadPage()をstatic化すると、今度はreloadPage()でself.webView.reload()が呼べません。

まだSwiftに慣れておらず、基礎的な理解が足りていないことは重々承知しておりますが、よい方法がございましたらご教示いただければ幸いです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • fuzzball

    2017/12/20 14:36

    MainとSubの関係は?MainのインスタンスをSubに渡せばいいのですが、何か思いつく方法はありませんか?

    キャンセル

  • teshiya

    2017/12/20 15:42

    いろいろ省略してしまいましたが、今回のアプリではSlideMenuControllerSwiftライブラリを利用して、いわゆるメニュー画面を表示しています。Main画面でスワイプすると左側にメニュー画面(Sub)が表示される仕組みです。このメニューにてリロードボタンがあり、ボタンを押すとMainのWeb画面をリロードしたいのです。

    キャンセル

回答 2

checkベストアンサー

+1

試せていませんが、
Subクラス内で、以下の様にSlideMenuControllerを経由してMainクラスが取得できないでしょうか。

if let slideMenuController = self.slideMenuController() {
    if let main = slideMenuController.mainViewController as? Main {
        // some
    }
}


GitHub - dekatotoro/SlideMenuControllerSwift
・「You can access from UIViewController」参照

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/20 17:39

    ありがとうございます、ご教示いただいた方法で、//someの箇所にmain.reloadPage()を実装したところ、コンパイルはOKでしたが、実行時にこの処理を通りませんでした…。

    キャンセル

  • 2017/12/20 18:32

    SlideMenuControllerがとれないのか、Mainがとれないのか。
    SubにMainの変数(例えば、var main: Main?)を追加し、MainとSubのインスタンスを生成したとき(多分、SlideMenuControllerに対して、mainControllerとleftControllerを設定したとき)に、sub.main = main とすればいいのではないでしょうか。
    Sub内でMainのインスタンスを作成しても、SlideMenuControllerのmainControllerに設定したMainとは別物のはずですから。

    キャンセル

  • 2017/12/21 11:32

    Mainのインスタンス化をヒントに、mainをstatic化する事でsubからmainの関数(reloadPage)を呼ぶことができました。
    ベストな実装ではないかもしれませんが、ひとまず想定通りの挙動になりました。ありがとうございました。

    キャンセル

  • 2017/12/21 13:13

    dsuzukiさんのコードでうまくいくはずなので、変なことをせずに解決した方がいいと思いますよ。

    キャンセル

+1

SlideMenuControllerSwiftをご利用とのことであれば、一時的にABどちらの画面も見えているように思いますが、アクティブな画面はどちらか一方です。
ですので、

Sub側で、(1)リロードする何かを伝え、(2)Mainに制御を渡す、(3)制御を受け取ったMain側はリロードするかどうかを判断するという流れになります。

SubからMainのreloadをするのではなく、あくまでMainが自身のreloadを行う。

1)リロードする状態をMainに伝える方法
UserDefaultsを利用するか、delegateを利用するか、Mainインスタンスを経由してMainのメンバ変数に設定するとかでしょうか。
2) openLeftとかopenRightとかでMainに
3) 1に応じて、leftDidCloseとかrightDidCloseあたりでリロードか否かを判断して、self.webView.reload() を呼ぶ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/20 17:27

    「アクティブな画面はどちらか一方です」が、どういう意味・意図なのか分かりませんが、Subが上にある状態(下にMain)でMainのテーブルを更新すると、その状態でMainの画面は更新されますよ。

    キャンセル

  • 2017/12/21 13:42

    fazzballさん>ご指摘ありがとうございます、どうも思い込みをしていたようです。勉強になりました、精進したいと思います。

    提示されたサンプルコードを見ると、MainもSubもどちらもSlideMenuControllerからの派生ではないため、SlideMenuControllerが保有するメンバとして利用していると推測されます。したがって、MainとSubが明示的な親子関係ではないです。そのため、「アクティブな画面はどちらか一方です」と表現しましたが、その場合だとしてもSubからの指示でMain(のUI部品)が更新されるのですよね。

    さて、Mainが一つであれば、MainをSlideMenuControllerにすれば十分と思われますが、Subがメニューとなり、実はMain1、Main2、、を切り替えて動作させるということであれば、現状で良いですし、その場合、delegateを用意して、そこで定義したメソッドを(Subから)呼び出すのが良さそうに思います。

    個人的には、SlideMenuControllerDelegateの各メソッドのパラメータにsenderがあればもう少し楽ができたかもしれませんね。

    キャンセル

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

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Swift

    6682questions

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

  • iOS

    3786questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。