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

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

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

【问题讨论】:

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

标签: ios objective-c uitableview uiimagepickercontroller


【解决方案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。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-04-26
            • 1970-01-01
            • 1970-01-01
            • 2020-01-21
            • 2016-01-27
            • 2013-10-25
            • 1970-01-01
            相关资源
            最近更新 更多