Ios xib中自定义TableCell中的PresentViewController

Ios xib中自定义TableCell中的PresentViewController,ios,objective-c,uitableview,uiimagepickercontroller,Ios,Objective C,Uitableview,Uiimagepickercontroller,我已经创建了自定义tableView控制器,在单元格内我放置了一个按钮来打开设备照片库。我的问题是,我无法从CustomCell.m打开imagePickerController,错误如下所示 请给我一些想法来解决我的问题。presentViewController:有关于Viewcontroller的消息。将控件从单元格委托给viewController,并使用同一行可以解决您的问题。UITableViewCell不响应presentViewController:消息。您需要一个UIViewC

我已经创建了自定义tableView控制器,在单元格内我放置了一个按钮来打开设备照片库。我的问题是,我无法从CustomCell.m打开imagePickerController,错误如下所示


请给我一些想法来解决我的问题。

presentViewController:
有关于Viewcontroller的消息。将控件从单元格委托给viewController,并使用同一行可以解决您的问题。UITableViewCell不响应
presentViewController:
消息。

您需要一个
UIViewController
从中显示。这里有几件事你可以做。一种方法是使用
changePicturePressed
回调方法创建自定义委托协议。然后,可以将包含的视图控制器指定为该委托,并在委托方法中执行表示


您可以做的另一件事是在初始化期间将
UIViewController
传递到单元格中,并将其设置为弱属性。然后,您可以使用该属性直接从单元格内部执行演示。

将您的按钮设为IBOutlet

然后在
cellForRowAtIndexPath
中为按钮指定目标

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

您需要viewcontroller来显示视图。您不能在TableViewCell上显示viewcontroller。

TableViewCell是一个视图,您不能在视图上显示,而UIViewController可以处理它。您应该将控件从单元格转移到保存tableview并为其创建自定义单元格的控制器

试着这样做:

自定义单元格
.h
类别:

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

@property (nonatomic, retain) id<changePictureProtocol> delegate;
加载此单元格的viewcontroller:

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

   cell.delegate = self;
}

-(void)loadNewScreen:(UIViewController *)controller;
{
  [self presentViewController:controller animated:YES completion:nil];
}
这是一个给你一个想法的伪代码

编辑:

Swift等价物:

CustomTableViewCell.swift
code:

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);
        }  
    }
}
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

    };
}
ViewController.swift
code:

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);
        }  
    }
}
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];

另一种方法是将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;
}

使用委托模式将您的单元格与viewcontroller绑定。您能详细说明您的答案吗@NeilGaliaskarovHey,你介意用Swift解释一下吗?无法从您的解释中转换为objc。非常感谢。@lukesIvi,检查我对swift等价物的编辑,如果您有任何困难,请告诉我。swift对我不起作用,我尝试显示打印(委托),但它只显示“nil”。这是我的代码:func collectionView(collectionView:UICollectionView,didSelectItemAtIndexPath indexath:nsindexath){print(“Hello outside”)print(委托)如果((委托?.respondsToSelector(“loadNewScreen:)!=nil){print(“Hello insinde”)let details=MovieDetail();委托?.loadNewScreen(details);print(委托)}@Evango,很抱歉反应太晚,刚刚看到你的消息。你设置了委托吗?
cell.delegate=self
?@neverhopess你能帮我一把吗?我理解,但似乎无法执行它。如果你将表视图和单元格构造为不在根视图控制器继承权中,那么这将不总是起作用“警告:试图显示其视图不在窗口层次结构中的对象!”!