カスタムtableViewControllerを作成しました。セル内に、デバイスのフォトライブラリを開くためのボタンを配置しました。私の問題は、CustomCell.mからimagePickerControllerを開くことができないことです。以下のエラーが表示されます。
私の問題を解決するためのアイデアを教えてください。
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
};
}
デリゲート変数またはインスタンス変数を提案する答えは正しいですが、ほとんどの場合、新しいコントローラーを提示するために特別なビューコントローラーを使用することは重要ではありません。このような場合、次の解決策ははるかに簡単です。アプリケーションのルートビューコントローラーを使用するだけです。
UIViewController* activeVC = [UIApplication sharedApplication].keyWindow.rootViewController;
[activeVC presentViewController:'new view controller'
animated:YES
completion:NULL];
presentViewController:
メッセージがViewcontrollerにあります。 CellからviewControllerに制御を委任し、同じ行を使用すると問題が解決します。 UITableViewCellはpresentViewController:
メッセージに応答しません。
これを行うもう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;
}
提示するにはUIViewController
が必要です。ここでできることがいくつかあります。 1つは、changePicturePressed
コールバックメソッドを使用してカスタムデリゲートプロトコルを作成することです。次に、含まれているView Controllerをそのデリゲートとして割り当て、デリゲートメソッドでプレゼンテーションを実行できます。
他にできることは、初期化中にUIViewController
をセルに渡し、それを弱いプロパティとして設定することです。次に、そのプロパティを使用して、セル内から直接プレゼンテーションを実行できます。
ボタンのIBOutletを作成します
次に、cellForRowAtIndexPath
でボタンにターゲットを指定します
CustomCell *customCell=[tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"];
[customCell.yourButton addTarget:self action:@selector(yourButtonAction:) forControlEvents:UIControlEventTouchUpInside];