You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.iOS容器视图调用PerformSegue报无指定segue标识符错误求助

解决Xamarin.iOS中PerformSegue找不到标识符的问题

嗨,我看了你的代码,问题出在你每次触发segue时都新建了一个ContainerViewController实例,而这个新实例根本没有和storyboard里的segue绑定,所以系统找不到'test1'这个标识符的segue,这就是报错的核心原因。

问题根源拆解

  1. 在TableSource的RowSelected方法里,你写了ContainerViewController containerController = new ContainerViewController();——这个新建的控制器是完全脱离storyboard的,它没有任何预定义的segue,自然会抛出找不到segue的异常。
  2. 另外在ContainerViewController的segueIdentifireRecievedFromParent方法里,你也多余地新建了一个ContainerViewController实例,这完全没必要,应该用当前控制器本身。

一步步修复方案

1. 让TableSource持有已存在的ContainerViewController引用

修改TableSource类,添加一个属性来接收已经在storyboard中创建好的ContainerViewController实例,而不是每次新建:

namespace PMApp.Classes {
    public class TableSource : UITableViewSource {
        List<string> TableItems;
        string CellIdentifier = "AreaCell";
        // 新增:保存已存在的容器控制器实例
        public ContainerViewController ContainerVC { get; set; }

        // 修改构造函数,传入容器控制器
        public TableSource(List<string> items, ContainerViewController containerVC) {
            TableItems = items;
            ContainerVC = containerVC;
        }

        // 保留原有RowsInSection、GetCell方法...

        public override void RowSelected(UITableView tableView, NSIndexPath indexPath) {
            // 使用传递过来的已存在的容器控制器,而不是新建
            ContainerVC.segueIdentifireRecievedFromParent(indexPath.Row);
            tableView.DeselectRow(indexPath, true);
        }

        // 保留原有newAlertView方法...
    }
}

2. 清理ContainerViewController中的多余代码

把segueIdentifireRecievedFromParent方法里新建容器控制器的代码删掉,直接用当前实例:

public void segueIdentifireRecievedFromParent(int selectedRow) {
    // 删掉这句无效的代码:ContainerViewController containerController = new ContainerViewController();
    if (selectedRow == 0) {
        segueIdentifier = "test1";
        PerformSegue(segueIdentifier, null);
    } else if (selectedRow == 1) {
        segueIdentifier = "test2";
        PerformSegue(segueIdentifier, null);
    }
}

3. 初始化TableSource时传入正确的容器控制器实例

在你创建TableSource的地方(比如主视图控制器或者容器控制器本身),把已经存在的ContainerViewController实例传进去:

// 假设你已经从storyboard获取到了containerVC实例
var yourItemList = new List<string> { "Item1", "Item2" };
var tableSource = new TableSource(yourItemList, containerVC);
yourTableView.Source = tableSource;

4. 最后确认storyboard的segue设置

  • 确保segue的源控制器是ContainerViewController,目标是你要切换的子控制器
  • 仔细核对segue的标识符是test1和test2,注意大小写(Objective-C是大小写敏感的)

额外优化建议:用实例化方式替代segue(更适合容器视图场景)

其实对于容器视图切换子控制器,直接从storyboard实例化子控制器比用segue更灵活,也能避免这类segue找不到的问题。你可以修改容器控制器的代码:

private void SwitchToChildViewController(Type childVcType) {
    // 移除旧的子控制器
    if (lastViewController != null) {
        lastViewController.WillMoveToParentViewController(null);
        lastViewController.View.RemoveFromSuperview();
        lastViewController.RemoveFromParentViewController();
    }

    // 从storyboard实例化新的子控制器
    var newChildVc = Storyboard.InstantiateViewController(childVcType.Name) as UIViewController;
    AddChildViewController(newChildVc);
    // 设置子视图大小匹配容器
    newChildVc.View.Frame = View.Bounds;
    View.AddSubview(newChildVc.View);
    newChildVc.DidMoveToParentViewController(this);

    lastViewController = newChildVc;
}

// 然后修改segueIdentifireRecievedFromParent方法:
public void segueIdentifireRecievedFromParent(int selectedRow) {
    if (selectedRow == 0) {
        SwitchToChildViewController(typeof(Test1ViewController));
    } else if (selectedRow == 1) {
        SwitchToChildViewController(typeof(Test2ViewController));
    }
}

这样就完全不需要依赖segue,代码也更清晰可控。

内容的提问来源于stack exchange,提问作者Jamie Leech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:08:55