2019年6月17日月曜日

横からメニューを出して画像を選択する方法

ボタンを押すと横からメニューが出てくる方法について実装してみたのでメモしておく。

イメージは、facebookとかでもよくある、メニューボタンを押すと、左側からメニュー画面が中途半端な位置まで移動してくる感じのを作ろうと思う。調べてみると、以下のサイトが分かりやすくまとめられていて、そんなに苦もなく作れた。


http://swift.hiros-dot.net/?p=377


ハンバーガーメニューっていうんですね。
横線3つだからハンバーガー?

サイトの通りにやったら特に問題なくつくれたのでここでは特に追記する必要はないけど、ナビゲーションバー上の画像サイズは20x20だった事だけ追記しておく。




メニュー画面は特に問題なかったけど、出したメニューからpickerviewを使ってカメラロールの画像を選択して、メニューの呼び出し元の画面に表示するところが苦労したのでこちらをメモしておく。

メニューの呼び出し先から画像を選択してメニューを閉じて、元のViewControllerのViewImageに画像を貼り付けようとViewDidApperにブレークポイントを置いてみても、呼び出されない!
ので、元ViewControllerのインスタンスを2通りの方法で呼び出す方法を試した。



<方法1>
以下のサイトのように、StoryBoardから該当ViewControllerを探して、その要素にアクセスする方法。


http://crossbridge-lab.hatenablog.com/entry/2015/12/14/073000
http://karel.tsuda.ac.jp/lec/swift/SwiftMoveView2/


技術的にはとっても参考になったけど、今回の場合はこれはうまくいかなかった。
呼び出す時に、別インスタンスと判断されて、メニューを呼び出した元 ViewControllerとは別物と判断されるため?と解釈して別の方法を試した。




<方法2>
主に3ステップで解決した。

【step1】どのクラスからもアクセス可能なParameterのシングルトンクラスを作って、この中に元ViewControllerのインスタンスを持たせた。(10行目)

【step2】元ViewControllerを作成した時にParameterクラスにインスタンスを持たせた。(43行目)

【step3】画像を選択してメニューを消した後にこのインスタンスを取得して、画像を表示させた。(59行目)



# Uncomment the next line to define a global platform for your project


//パラメータクラス
class Parameter:NSObject {
    
    //元画像
    var OriginalImage:UIImage? = nil
    //元ViewController
    var MainView:ViewController? = nil
    
    static let sharedInstance: Parameter = Parameter()
    private override init(){
    }
    //set
    func SetOriginalImage(image: UIImage) {
        OriginalImage = image
    }
    func SetMainView(view: ViewController) {
        MainView = view
    }
    //get
    func GetOriginalImage() -> UIImage? {
        return OriginalImage
    }
    func GetMainView() -> ViewController? {
        return MainView
    }
}


//元ViewController
class ViewController: UIViewController{

    @IBOutlet weak var IV_Main: UIImageView!

    //画面が初期化時に呼ばれる
    override func viewDidLoad() {
        super.viewDidLoad()
        //広告の実装
        *****
        //自身をパラメータクラスに格納する
        Parameter.sharedInstance.SetMainView(view: self)
    }
    
}


//MenuController
class FileMenuViewViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    *****

    //イメージピッカーが「選択」された場合に呼ばれる
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        //元画像をパラメータクラス受け渡し
        Parameter.sharedInstance.SetOriginalImage(image: info[.originalImage] as! UIImage)
        //元ViewControllerの画面に画像を貼り付け
        Parameter.sharedInstance.GetMainView()?.IV_Main.image = info[.originalImage] as? UIImage
        //Picker画面を消す
        dismiss(animated: true, completion: nil)
        //ファイルメニュー画面を消す
        UIView.animate(
            withDuration: 0.2,
            delay: 0,
            options: .curveEaseIn,
            animations: {self.V_FileMenu.layer.position.x = -self.V_FileMenu.frame.width},
            completion: {bool in self.dismiss(animated: true, completion: nil)}
        )
    }
    
}


読み込んだ元画像は57行目でパラメータクラスに格納しているので、他のクラスから元画像にアクセスする場合はParameterクラスから元画像を引っ張れるようにした。

0 件のコメント:

コメントを投稿