Xcode 4.6.1 iOS 6使用故事板
我的问题是这个
我在UIViewController中的UIView上有一个带有动态原型单元的UITableView(它本身嵌入在导航控制器中),我想从一个特定的单元格转到另一个视图
(在任何人建议我应该使用UITableViewController之前,我确实在UIView上有其他东西,所以我出于某种原因设置了这种方式。)
现在我不确定如何创建segue
如果我从原型UITableViewCell拖动来创建一个segue,所有生成的单元格会自动调用segue - 当我只需要一个这样做时。这是正常的行为,如果我通过从UITableViewController拖动创建segue并调用[self performSegueWithIdentifier:....来自我的didSelectRowAtIndexPathMethod,因此只有我想要执行此segue的特定单元格触发它,我会解决这个问题
在这种情况下我没有UITableViewController - 只是UIView上的UITableView,它是UIViewController子类的一部分
我一直在玩,我刚刚发现我无法从UITableView拖动 - 不允许你这样做,所以这是一个deadend。
我唯一留下的选择是从UIViewController拖出
所以我试过了,当然XCode在执行segue线上抛出一个错误告诉我我...没有'LocationTV'的可见界面声明了选择器performSegueWithIdentifier。 LocationTv是我的tableview子类。
在这种情况下尝试调用新视图的正确方法是什么
谢谢
西蒙
答案 0 :(得分:5)
首先,segues
只能在UIViewControllers
之间使用。因此,如果您想在同一视图控制器上的两个视图之间执行segue,那是不可能的。
但是如果你想在两个视图控制器之间执行一个segue,那么应该通过一个视图(在第一个视图控制器内)的动作触发segue,这是可能的。
所以在你的情况下,如果我理解了这个问题,你想在点击自定义UIView
内的UITableView的第一个单元格时执行一个segue。最简单的方法是在自定义UIView
上创建一个委托,该委托将由包含自定义UIView
的UIViewController实现,当调用委托方法时,您应该执行segue,这是一个简短的示例:
<强> YourCustomView.h 强>
@protocol YourCustomViewDelegate <NSObject>
-(void)pleasePerformSegueRightNow;
@end
@interface YourCustomView : UIView {
UITableView *theTableView; //Maybe this is a IBOutlet
}
@property(weak, nonatomic) id<YourCustomViewDelegate>delegate;
<强> YourCustomview.m 强>
@implementation YourCustomview
@ synthesise delegate;
//make sure that your table view delegate/data source are set properly
//other methods here maybe
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row == 0) { //or any other row if you want
if([self.delegate respondsToSelector:@selector(pleasePerformSegueRightNow)]) {
[self.delegate pleasePerformSegueRightNow];
}
}
}
<强> YourTableViewController.h 强>
@interface YourTableViewController : UIViewController <YourCustomViewDelegate> {
//instance variables, outlets and other stuff here
}
<强> YourTableViewController.m 强>
@implementation YourTableViewController
-(void)viewDidLoad {
[super viewDidLoad];
YourCustomView *customView = alloc init....
customView.delegate = self;
}
-(void)pleasePerformSegue {
[self performSegueWithIdentifier:@"YourSegueIdentifier"];
}
您可以为您的委托创建任何方法,也可以自定义行为,这只是一个如何操作的简单示例。
答案 1 :(得分:3)
我的解决方案
我最终使用了委托模式
我从我的UIViewController中拖出了一个segue - 特别是从viewController图标(带有白色方块的橙色圆圈)中拖出 - 来自故事板视图下方的名称栏 - 尽管你也可以从侧边栏拖动)我认为我想要转向的观点。
我需要从表格视图中的表格视图单元格中触发此segue。
TableView位
所以我在tableview头文件中声明了一个协议 - 名为LocationTV.h - 如下所示
@protocol LocationTVSegueProtocol <NSObject>
-(void) makeItSegue:(id)sender;
@end
在下面我宣布一个属性来保存我的代表
@property (nonatomic, strong) id<LocationTVSegueProtocol> makeSegueDelegate;
要实际触发segue,我在didSelectRowAtIndexPath方法中的makeSequeDelegate上调用了makeItSegueMethod
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section) {
DLog(@"selected row %d",indexPath.row);
case dLocation:
{
if(indexPath.row == 2){
[_makeSegueDelegate makeItSegue:self];
} else if (indexPath.row == 7){
UIViewController位
并将我的UIViewController(名为MultiTableHoldingVC)设置为实现该协议
@interface MultiTableHoldingView : UIViewController
<EnviroTVProtocol,LocationTVSegueProtocol> {
}
下面我在我的类方法列表中声明了protocol方法(虽然我不确定是否有必要,因为编译器应该知道该方法,因为实现协议的decalration本质上是一个实现的承诺这种方法)
-(void) makeItSegue:(id)sender;
然后在我的UIViewController的实现文件中,我写了一个基本上只调用preformSegueWithIdentifier的方法
-(void) makeItSegue:(id)sender{
[self performSegueWithIdentifier:@"ChooseCountryNow"
sender:sender];
}
并将它们全部链接在一起,就像在头文件中我声明我的tableView实例一样,如下所示
@property (strong, nonatomic) IBOutlet LocationTV *dsLocationTV;
我必须设置表视图委托属性为self - 我在UIViewControllers中做了 - (void)ViewDidLoad方法
_dsLocationTV.makeSegueDelegate = self;
这一切似乎都是一种调用方法来调用方法的方法,并且allprog建议更简单(我不能为我的生活解决为什么它为我抛出错误)但这很好用。感谢allprog和danypata的建议。
希望这对那里的人有帮助
答案 2 :(得分:0)
performSegueWithIdentifier:
是UIViewController类的一个方法。您无法在UITableView实例上调用它。让您的视图控制器实现UITableViewDelegate协议并将其设置为UITableView的委托。
另一个选择是你不使用segues。在同一个委托方法中执行:
OtherViewController ov = [[OtherViewController alloc] init<<some initializer>>];
// Or in case of storyboard:
OtherViewController ov = [self.storyboard instantiateViewControllerWithIdentifier:@"ovidentifier"];
// push view controller
[self.navigationController pushViewController:ov animated:YES];
如果委托对象与视图控制器不同,那么最简单的解决方案是将弱属性添加到委托的类中,该类保留对viewController的引用,如下所示:
@property (weak) UIViewController *viewController;
并将其设置在viewController的viewDidLoad
- (void) viewDidLoad {
self.tableView1.viewController = self;
}
确保tableView1
属性声明如下:
@property (IBACTION) (weak) SpecialTableView *tableView1;
有时使用故事板比自己编写代码更痛苦。