web-dev-qa-db-ja.com

xibのカスタムテーブルセルからViewControllerを表示します

カスタムtableViewControllerを作成しました。セル内に、デバイスのフォトライブラリを開くためのボタンを配置しました。私の問題は、CustomCell.mからimagePickerControllerを開くことができないことです。以下のエラーが表示されます。 enter image description here

私の問題を解決するためのアイデアを教えてください。

11
Ramdhas

TableViewCellはビューであり、ビューでpresentすることはできません。代わりに、UIViewControllerがそれを処理できます。セルから、テーブルビューを保持し、そのカスタムセルを作成するコントローラーにコントロールを転送する必要があります。

このようにしてみてください:

カスタムセル.hクラス:

@protocol changePictureProtocol <NSObject>
-(void)loadNewScreen:(UIViewController *)controller;
@end

@property (nonatomic, retain) id<changePictureProtocol> delegate;

次にSynthesize it in。m。

これをmファイルに追加します。

-(IBAction)changePicture:(id)sender
{
    // ..... blah blah
    [self.delegate loadNewScreen:picker];
}

このセルをロードするビューコントローラ:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   // create cell here

   cell.delegate = self;
}

-(void)loadNewScreen:(UIViewController *)controller;
{
  [self presentViewController:controller animated:YES completion:nil];
}

それはあなたにアイデアを与えるための擬似コードです。

編集:

スイフト相当:

CustomTableViewCell.Swiftコード:

protocol ChangePictureProtocol : NSObjectProtocol { 
    func loadNewScreen(controller: UIViewController) -> Void;  
}

class CustomTableViewCell: UITableViewCell {

    // Rest of the class stuff

    weak var delegate: ChangePictureProtocol?

    @IBAction func changePicture(sender: AnyObject)->Void
    {
        var pickerVC = UIImagePickerController();
        if((delegate?.respondsToSelector("loadNewScreen:")) != nil)
        {
           delegate?.loadNewScreen(pickerVC);
        }  
    }
}

ViewController.Swiftコード:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    var cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier") as CustomTableViewCell!

    cell.delegate = self;

    return cell;
}

func loadNewScreen(controller: UIViewController) {
    self.presentViewController(controller, animated: true) { () -> Void in

    };
}
30
NeverHopeless

デリゲート変数またはインスタンス変数を提案する答えは正しいですが、ほとんどの場合、新しいコントローラーを提示するために特別なビューコントローラーを使用することは重要ではありません。このような場合、次の解決策ははるかに簡単です。アプリケーションのルートビューコントローラーを使用するだけです。

UIViewController* activeVC = [UIApplication sharedApplication].keyWindow.rootViewController;
[activeVC presentViewController:'new view controller'
                       animated:YES
                     completion:NULL];
11
LaborEtArs

presentViewController:メッセージがViewcontrollerにあります。 CellからviewControllerに制御を委任し、同じ行を使用すると問題が解決します。 UITableViewCellはpresentViewController:メッセージに応答しません。

1
Rajesh

これを行うもう1つの方法は、CustomCellのコントローラーの参照をCustomCellに渡し、それを使用して新しいコントローラーを提示することです。

迅速:

CustomCell.Swift

class CustomTableViewCell: UITableViewCell {

    // Rest of the class stuff

    var parentViewController: UIViewController? = nil

    gotoNewControllerBtn.addTarget(self, action: #selector(gotoNewController), for: .touchUpInside)

    func gotoNewController() {
        let newViewController = NewViewController()
        parentViewController.present(newViewController, animated: true, completion: nil)
    }
}

ViewController.Swift

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    var cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier") as CustomTableViewCell!

    cell.parentViewController = self;

    return cell;
}
1
crc442

提示するにはUIViewControllerが必要です。ここでできることがいくつかあります。 1つは、changePicturePressedコールバックメソッドを使用してカスタムデリゲートプロトコルを作成することです。次に、含まれているView Controllerをそのデリゲートとして割り当て、デリゲートメソッドでプレゼンテーションを実行できます。

他にできることは、初期化中にUIViewControllerをセルに渡し、それを弱いプロパティとして設定することです。次に、そのプロパティを使用して、セル内から直接プレゼンテーションを実行できます。

1
Dima

ボタンのIBOutletを作成します

次に、cellForRowAtIndexPathでボタンにターゲットを指定します

CustomCell *customCell=[tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"];
[customCell.yourButton addTarget:self action:@selector(yourButtonAction:) forControlEvents:UIControlEventTouchUpInside];
1
Jay Gajjar