我创建了自定义的“tableView Controller”,在单元格内放置了一个按钮,以打开设备照片库。我的问题是,我无法从CustomCell.m中打开imagePickerController,它显示如下错误。请提供一些解决方法。
![enter image description here](https://istack.dev59.com/rdWOH.webp)
![enter image description here](https://istack.dev59.com/rdWOH.webp)
TableViewCell是一个视图,你不能在视图上执行present
操作,而是应该由UIViewController处理。你应该将控制权从单元格转移到持有tableview并为其创建自定义单元格的控制器。
可以尝试以下方法:
自定义单元格.h
类:
@protocol changePictureProtocol <NSObject>
-(void)loadNewScreen:(UIViewController *)controller;
@end
@property (nonatomic, retain) id<changePictureProtocol> delegate;
然后在.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
};
}
提出使用委托或实例变量的答案是正确的,但是在大多数情况下,使用特殊的视图控制器来呈现新控制器并不重要。 在这些情况下,以下解决方案要简单得多:只需使用应用程序的根视图控制器:
UIViewController* activeVC = [UIApplication sharedApplication].keyWindow.rootViewController;
[activeVC presentViewController:'new view controller'
animated:YES
completion:NULL];
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;
}
将您的按钮创建为IBOutlet
然后在cellForRowAtIndexPath
中将目标分配给按钮
CustomCell *customCell=[tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"];
[customCell.yourButton addTarget:self action:@selector(yourButtonAction:) forControlEvents:UIControlEventTouchUpInside];
presentViewController:
是用于视图控制器的消息。将控制从单元格委托给视图控制器,并使用相同的行即可解决问题。UITableViewCell 不响应 presentViewController:
消息。
UIViewController
来进行呈现。这里有几个可行的方案。一种方法是创建一个自定义委托协议,其中包含一个changePicturePressed
回调方法。然后,您可以将包含视图控制器作为该委托分配,并在委托方法中执行呈现。UIViewController
传递到单元格中,并将其设置为弱属性。然后,您可以直接从单元格内使用该属性执行呈现。你需要一个视图控制器来呈现视图。你不能在表格视图单元上呈现视图控制器。