调用iOS Alert时出现UI一致性错误
我有一个iOS Xamarin项目,我收到以下错误:
UIKit Consistency error: you are calling a UIKit method that can only be invoked from the UI thread.
以下代码会发生此错误:
在我的欢迎视图页面中,我有一个名为SyncButton
的button被点击。 该button的点击应该使用REST将数据与服务器进行同步。
在我的WelcomeController中我有:
.... SyncButton.TouchUpInside += async (object sender, EventArgs e) => { SyncButton.Enabled = false; await welcomeDelegate.syncButtonCore (cred, iOSErrorAlert); SyncButton.Enabled = true; }; .... public void iOSErrorAlert(string LoginErrorTitle, string LoginErrorMessage){ var Alert = UIAlertController.Create (LoginErrorTitle, LoginErrorMessage, UIAlertControllerStyle.Alert); Alert.AddAction (UIAlertAction.Create ("OK", UIAlertActionStyle.Cancel, null)); PresentViewController (Alert, animated: true, completionHandler: null); }
警报应该在发生超时或其他错误时发生。
SyncButtonCore()
包含在一个类似如下的委托类中:
public async Task syncButtonCore(UserCredentials cred, RequestWithAlertDelegate.ErrorAlert NativeAlert){ await Task.Run (async ()=>{ RequestWithAlertDelegate requestWithAlert = new RequestWithAlertDelegate(); string URL = URLs.BASE_URL + URLs.CASELOAD + "/" + cred.PID; await requestWithAlert.RequestWithRetry(URL, cred.UserID, cred.Password, NativeAlert, null, async delegate (string Response1){...}, 1);
我的RequestWithAlert
类是:
public async Task RequestWithRetry (string URL, string UserID, string Password, ErrorAlert NativeAlert, SyncAction Action, AsyncAction Action2, int times) { ...make sure legit credentials... if (LoginError) { NativeAlert (LoginErrorTitle, LoginErrorMessage); }
在最后一位代码中,我在NativeAlert()函数中得到我的错误。 最终抛出我的代码在开始提到的UIKit错误
var Alert = UIAlertController.Create (LoginErrorTitle, LoginErrorMessage, UIAlertControllerStyle.Alert);
我不知道我在做什么错在这里,为什么我不被允许创build这个警报,因为我在我的UIThread应该是正确的我的WelcomeController中定义它?
问题出在我的iOSErrorAlert()
函数。 我需要用InvokeOnMainThread()
来包围它,因为UI操作应该在主线程中执行(我没有做,因为我把它传递给其他类/线程)。 谢谢@ Paulw11的评论。
不得不取代这个:
public void iOSErrorAlert(string LoginErrorTitle, string LoginErrorMessage){ var Alert = UIAlertController.Create (LoginErrorTitle, LoginErrorMessage, UIAlertControllerStyle.Alert); Alert.AddAction (UIAlertAction.Create ("OK", UIAlertActionStyle.Cancel, null)); PresentViewController (Alert, animated: true, completionHandler: null); }
有了这个:
public void iOSErrorAlert(string LoginErrorTitle, string LoginErrorMessage){ InvokeOnMainThread (() => { var Alert = UIAlertController.Create (LoginErrorTitle, LoginErrorMessage, UIAlertControllerStyle.Alert); Alert.AddAction (UIAlertAction.Create ("OK", UIAlertActionStyle.Cancel, null)); PresentViewController (Alert, animated: true, completionHandler: null); }); }