【问题标题】:Error in ui kit Consistency errorui 套件中的错误 一致性错误
【发布时间】:2016-08-24 10:29:12
【问题描述】:

我在访问视图控制器 .cs 文件中的文本框时遇到问题

 async partial void loginUser(UIButton sender)

{

    // Show the progressBar as the MainActivity is being loade


    Console.WriteLine("Entered email : " + txtEmail.Text);


        // Create user object from entered email
        mCurrentUser = mJsonHandler.DeserialiseUser(txtEmail.Text);
        try
        {

            Console.WriteLine("Starting network check");
            // Calls email check to see if a registered email address has been entered
            if (EmailCheck(txtEmail.Text) == true)
            {
                await  CheckPassword();
            }
            else
            {
                UIAlertView alert = new UIAlertView()
                {
                    Title = "Login Alert",
                    Message = "Incorrect email or password entered"
                };
                alert.AddButton("OK");
                alert.Show();

            }


        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine("An error has occured: '{0}'", ex);
        }

正是在这个函数中,它抱怨它无法访问 aynsc 方法上的文本框

    public Task CheckPassword()
    {

   return Task.Run(() =>
    {
            // Creates instance of password hash to compare plain text and encrypted passwords.
            PasswordHash hash = new PasswordHash();
            // Checks password with registered user password to confirm access to account.
            if (hash.ValidatePassword(txtPassword.Text ,mCurrentUser.password)==true)
            {
                Console.WriteLine("Password correct");


                UIAlertView alert = new UIAlertView()
                {
                    Title = "Login Alert",
                    Message = "Password Correct Loggin In"
                };
                alert.AddButton("OK");
                alert.Show();
                //insert intent call to successful login here.

            }
            else
            {
                UIAlertView alert = new UIAlertView()
                {
                    Title = "Login Alert",
                    Message = "Incorrect email or password entered"
                };
                alert.AddButton("OK");
                alert.Show();

            }
            Console.WriteLine("Finished check password");
        });
    }

错误发生在这一行:

txtPassword.Text 

错误如下:

UIKit.UIKitThreadAccessException: UIKit 一致性错误:你是 调用只能从 UI 线程调用的 UIKit 方法。

即使密码正确,我的密码正确也不会显示。 我必须在单独的线程上运行 UI 警报吗?

【问题讨论】:

    标签: c# xamarin xamarin.ios


    【解决方案1】:

    任何 UIKit 方法都必须从 UI 线程(或主线程、主队列等)调用。这确保了 UI 的一致性。 Xamarin 在调试模式下对所有 UIKit 方法添加检查,如果您尝试使用后台线程更改 UI,则会引发该异常。

    解决方案很简单:只从 UI 线程修改 UI。这实质上意味着,如果您使用前面带有“UI”的类,您可能应该从 UI 线程中执行此操作。 (这是经验法则,在 UI 线程上还有其他时间)。

    如何在这个神秘的 UI 线程上获取我的代码?我很高兴你问。在 iOS 中,您有几个选择:

    • 当在 NSObject 的子类中时,InvokeOnMainThread 可以解决问题。
    • 在任何地方,CoreFoundation.DispatchQueue.MainQueue.DispatchAsync 将始终有效。

    这两个方法都只接受一个Action,它可以是一个 lambda 或一个方法。

    所以在您的代码中,如果我们添加一个InvokeOnMainThread(因为我认为这是在您的UIViewController 子类中)...

     public Task CheckPassword()
     {
    
         return Task.Run(() =>
         {
            // Creates instance of password hash to compare plain text and encrypted passwords.
            PasswordHash hash = new PasswordHash();
            // Checks password with registered user password to confirm access to account.
            InvokeOnMainThread(() => {
                if (hash.ValidatePassword(txtPassword.Text ,mCurrentUser.password)==true)
                {
                    Console.WriteLine("Password correct");
    
    
                    UIAlertView alert = new UIAlertView()
                    {
                        Title = "Login Alert",
                        Message = "Password Correct Loggin In"
                    };
                    alert.AddButton("OK");
                    alert.Show();
                    //insert intent call to successful login here.
    
                }
                else
                {
                    UIAlertView alert = new UIAlertView()
                    {
                        Title = "Login Alert",
                        Message = "Incorrect email or password entered"
                    };
                    alert.AddButton("OK");
                    alert.Show();
    
                }
            });
            Console.WriteLine("Finished check password");
        });
    }
    

    【讨论】:

    • 很好的答案,谢谢,我也遇到了一个小问题,我似乎无法将另一个视图推送到该线程中,我希望它在登录成功时转到 contactInfo 的情节提要 ID
    • 我正在努力解决推送我的视图问题,所以感谢 dylan 的帮助
    • 感谢您的回答,以下对我有用。 CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() => { // UI 代码在这里 });
    【解决方案2】:

    也许这对某人有帮助。因此,我将添加解决我的问题的方法,这与流氓相同。 遵循在 iOS 中使用时避免 xamarin 表单中出现这种一致性错误的代码

     await Task.Run(async () =>
                {
                    await Device.InvokeOnMainThreadAsync(async () =>
                    {
                        await MaterialDialog.Instance.SnackbarAsync(message: "Bla bla bla",
                                               msDuration: MaterialSnackbar.DurationShort).ConfigureAwait(false);
    
                    }).ConfigureAwait(false);
    
                }).ConfigureAwait(false);  
    

    【讨论】:

    • 已经选择了一个接受的答案,请不要创建答案,因为甚至没有代表评论它不是堆栈溢出方式,但谢谢你基本上复制了他发布的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    • 2015-10-24
    相关资源
    最近更新 更多