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

如何解决Xamarin.Forms跨平台iOS应用支付界面跳转外部窗口问题

Xamarin.Forms Shell iOS 第三方支付界面跳转外部窗口问题解决

问题背景

基于Xamarin.Forms 5.0.0.2478 + Shell特性开发跨平台应用,已集成第三方支付SDK,Android平台支付流程正常,但iOS平台支付界面会跳转到外部窗口,而非在应用内加载。核心问题在于错误处理了iOS根视图控制器:

  • AppDelegate继承自FormsApplicationDelegate,手动创建空UIWindow会与Forms自动初始化的窗口冲突,导致KeyWindow.RootViewController无效
  • 依赖服务中尝试直接Present自定义VC,但未获取到Shell应用对应的正确原生视图控制器上下文

解决方案

1. 修正AppDelegate初始化逻辑

移除手动创建UIWindow的代码,FormsApplicationDelegate在LoadApplication时已经自动完成了UIWindow和根视图控制器的初始化,手动创建会破坏Shell的导航结构:

UIWindow window;
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    global::Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental");
    global::Xamarin.Forms.Forms.Init();

    // 加载Forms应用,自动初始化窗口和根VC
    LoadApplication(new App());

    return base.FinishedLaunching(app, options);
}

2. 获取正确的iOS顶级视图控制器

在iOS依赖服务中,需要获取Shell应用对应的当前活跃顶级视图控制器,而非空的根VC:

public void PaymentRequest(PaymentData paymentData)
{
    Payment payment = new Payment();
    payment.RefNo = paymentData.ReferenceNumber;
    // ... 填充其他支付参数

    PayObject payObj = new PayObject();
    // ... 配置PayObject参数

    // 获取支付SDK返回的视图
    UIView responseView = payObj.Checkout(payment);
    responseView.Frame = UIScreen.MainScreen.Bounds;

    // 创建承载支付视图的控制器
    UIViewController responseVC = new UIViewController();
    responseVC.View = responseView;

    // 获取当前活跃的顶级视图控制器
    UIViewController topVC = null;

    // 优先通过Xamarin.Forms Platform获取当前上下文的VC
    if (Xamarin.Forms.Platform.iOS.Platform.Current != null)
    {
        topVC = Xamarin.Forms.Platform.iOS.Platform.Current.ViewController;
    }

    // 备选方案:遍历所有窗口找到活跃的根VC
    if (topVC == null)
    {
        foreach (var window in UIApplication.SharedApplication.Windows)
        {
            if (window.IsKeyWindow && window.RootViewController != null)
            {
                topVC = window.RootViewController;
                break;
            }
        }
    }

    // 递归找到最上层的模态VC(处理Shell多层导航场景)
    while (topVC?.PresentedViewController != null)
    {
        topVC = topVC.PresentedViewController;
    }

    // 模态展示支付界面
    topVC?.PresentViewController(responseVC, true, null);
}

额外说明

  • 如果第三方支付SDK支持传入UINavigationController,可以直接使用topVC.NavigationController传入,这样支付界面会以导航栈推入的方式展示,更符合iOS应用的交互逻辑
  • 避免直接使用UIApplication.SharedApplication.KeyWindow.RootViewController,Shell应用中该值可能并非当前活跃的导航上下文

内容的提问来源于stack exchange,提问作者Thamarai T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:30:53