c# - 更改定时器 iOS Xamarin 的背景

标签 c# ios xamarin xamarin.ios visual-studio-mac

我正在构建一个 iOS 应用程序,我试图每隔几秒钟更改一次背景图像。我使用此处的代码设置了一个计时器:https://developer.xamarin.com/api/type/System.Threading.Timer/

我的代码是这样的:

using System;
using System.Threading;

using UIKit;

namespace TestApp
{
    public partial class ViewController : UIViewController
   {
    // New Timer
    class BackgroundTimer
    {
        public int counter = 0;
        public Timer tmr;

    }
    // Load screen
    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        BackgroundTimer s = new BackgroundTimer();
        // Create the delegate that invokes methods for the timer.
        TimerCallback timerDelegate = new TimerCallback(ChangeBackground);

        // Create a timer that waits three seconds, then invokes every three seconds.
        Timer timer = new Timer(timerDelegate, s, 3000, 3000);

        // Keep a handle to the timer, so it can be disposed.
        s.tmr = timer;

        void ChangeBackground(Object state)
        {
            BackgroundTimer t = (BackgroundTimer)state;
            t.counter++;
            Background.Image = UIImage.FromBundle("HydePark");
        }

当我在模拟器中运行它时,出现以下错误:

UIKit.UIKitThreadAccessException has been thrown

UIKit Consistency error: you are calling a UIKit method that can only 
be invoked from the UI thread.

我不确定那是什么意思。

更新/编辑:(2017 年 7 月 23 日)

下面的问题解决了我的问题。我想循环图像,所以我制作了一个随机生成器,但它只循环图像一次。

 // Load screen
    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        // Random number generator 
        Random RandomImage = new Random();
        int RandomImg = RandomImage.Next(1, 6);
        string image = "";

        // Switch statement for displaying different messages
        switch (RandomImg)
        {
            case 1:
                image = "Image1";
                break;
            case 2:
                image = "Image2";
                break;
            case 3:
                image = "Image3";
                break;
            case 4:
                image = "Image4";
                break;
            case 5:
                image = "Image5";
                break;
        }

        BackgroundTimer s = new BackgroundTimer();
        // Create the delegate that invokes methods for the timer.
        TimerCallback timerDelegate = new TimerCallback(ChangeBackground);

        // Create a timer that waits three seconds, then invokes every three seconds.
        Timer timer = new Timer(timerDelegate, s, 3000, 3000);

        // Keep a handle to the timer, so it can be disposed.
        s.tmr = timer;

        void ChangeBackground(Object state)
        {
            BackgroundTimer t = (BackgroundTimer)state;
            t.counter++;
            InvokeOnMainThread(() =>
            {
                Background.Image = UIImage.FromBundle(image);
            });

        }

最佳答案

更新 UI 需要您在主线程(UI 线程)上,将 Background.Image 调用放在 InvokeOnMainThread 中将解决 UIKit异常:

void ChangeBackground(Object state)
{
    BackgroundTimer t = (BackgroundTimer)state;
    t.counter++;
    InvokeOnMainThread(() =>
    {
        Background.Image = UIImage.FromBundle("HydePark");
    });
}

Xamarin 有一个指南,概述了为什么/如何需要完成这些工作:

关于c# - 更改定时器 iOS Xamarin 的背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45261705/

相关文章:

c# - 使用泛型可以将提供的类型限制为内置类型吗?

c# - 为什么这个语法 List.Add(item);{//some code }

ios - 我在 swift 3 中不断收到 "signal 1: SIGABRT",我不知道如何解决它

ios - 检测应用程序何时进入我的 View 背景的最佳方法是什么?

c# - 添加到列表的并行循环

ios - Cocoa Touch 框架中 Unresolved 公共(public)类

c# - Xamarin Forms 访问 ListView

xamarin 表单与 mvvmcross 一起使用

android - 将 Xamarin 表单更新到 5.0.0.2401 后,Xamarin 表单 android 抛出空异常

c#: ExecuteNonQuery() 返回 -1