来自xib中自定义TableCell的PresentViewController

Posted

技术标签:

【中文标题】来自xib中自定义TableCell的PresentViewController【英文标题】:PresentViewController from custom TableCell in xib 【发布时间】:2014-04-07 05:21:01 【问题描述】:

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

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

【问题讨论】:

使用委托模式将您的单元格与视图控制器绑定。 你能详细说明你的答案吗? @NeilGaliaskarov 【参考方案1】:

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

试试这样:

自定义单元格.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];

它是一个伪代码,可以给你一个想法。

编辑:

Swift 等价物:

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

    ;

【讨论】:

嘿,你介意用 Swift 解释一下吗?从您的解释中将其从 objc 转换时遇到问题。非常感谢。 @lukesIvi,检查我的编辑是否有 swift 等效项,如果您有任何困难,请告诉我。 swift 对我不起作用,我试图显示 print(delegate) 但它只有“nil”这是我的代码: func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) print("你好外面") print(delegate) if((delegate?.respondsToSelector("loadNewScreen:")) != nil) print("Hello insinde") let details = MovieDetail();委托?.loadNewScreen(详细信息);打印(委托) @EvanNgo,抱歉回复晚了,刚刚看到你的消息。你设置委托了吗? cell.delegate = self ? @NeverHopeless 你能帮帮我吗?我明白了,但似乎无法执行【参考方案2】:

提出委托或实例变量的答案是正确的,但是,在大多数情况下,使用特殊的视图控制器来呈现新控制器并不重要。 在这些情况下,以下解决方案要简单得多:只需使用应用程序根视图控制器:

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

【讨论】:

如果您将表格视图和单元格构造为不在根视图控制器层次结构中,这将不会总是有效“警告:尝试在 上呈现 视图不在窗口层次结构中!【参考方案3】:

presentViewController: 消息用于 Viewcontroller。将控件从 Cell 委托给 viewController 并使用同一行将解决您的问题。 UITableViewCell 不响应presentViewController: 消息。

【讨论】:

【参考方案4】:

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

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

【讨论】:

【参考方案5】:

为您的按钮制作 IBOutlet

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

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

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

您需要 viewcontroller 来呈现视图。您不能在 tableviewcells 上显示 viewcontroller。

【讨论】:

以上是关于来自xib中自定义TableCell的PresentViewController的主要内容,如果未能解决你的问题,请参考以下文章

编辑 TableView 时自定义 TableCell 中没有缩进

自定义tableview的xib怎么加载

在 Interface Builder 中自定义 UITableViewCell

如何链接两个xib?

显示来自 Xib 的自定义视图

如何擦除 iPhone 中自定义 UIView 上的手指画