官术网_书友最值得收藏!

Displaying progress

In this recipe, we will discuss how to display the progress of known length.

Getting ready

In this recipe, we will talk about the UIProgressView control. This control provides a similar functionality to the ProgressBar control in .NET. Create a new iPhone Single View Application project in Xamarin Studio and name it ProgressApp.

How to do it...

The following are the steps for using the UIProgressView class. Note that in this recipe, we will add all the controls programmatically without the use of Interface Builder.

  1. Add the following using directives in the ProgressAppViewController class file:
    using System.Drawing;
    using System.Threading;
    using System.Threading.Tasks;
  2. Add the following fields in the class:
    UILabel labelStatus;
    UIButton buttonStartProgress;
    UIProgressView progressView;
    float incrementBy = 0f;
  3. Enter the following code in the ViewDidLoad override:
    // Initialize the label
    this.labelStatus = new UILabel (new RectangleF (60f, 60f, 200f, 50f));
    this.labelStatus.AdjustsFontSizeToFitWidth = true;
    // Initialize the button
    this.buttonStartProgress = UIButton.FromType (UIButtonType.System);
    this.buttonStartProgress.Frame = new RectangleF (60f, 400f, 200f, 40f);
    
    this.buttonStartProgress.SetTitle ("Tap to start progress!", UIControlState.Normal);
    this.buttonStartProgress.TouchUpInside += delegate {
      // Disable the button
      this.buttonStartProgress.Enabled = false;
      this.progressView.Progress = 0f;
      // Start a progress
      Task.Factory.StartNew(this.StartProgress);
    } ;
    
    // Initialize the progress view
    this.progressView = new UIProgressView (new RectangleF (60f, 200f, 200f, 50f));
    
    // Set the progress view's initial value
    this.progressView.Progress = 0f;
    
    // Set the progress increment value
    // for 10 items
    this.incrementBy = 1f / 10f;
    
    this.View.AddSubview(this.labelStatus);
    this.View.AddSubview(this.buttonStartProgress);
    this.View.AddSubview(this.progressView);
  4. Add the following method in the class:
    private void StartProgress ()
    {
      float currentProgress = 0f;
      while (currentProgress < 1f)
      {
        Thread.Sleep(1000);
        this.InvokeOnMainThread(delegate {
          // Advance the progress
          this.progressView.Progress += this.incrementBy;
          currentProgress = this.progressView.Progress;
          // Set the label text
          this.labelStatus.Text = string.Format("Current value: { 0}", Math.Round((double)this.progressView.Progress, 2));
          if (currentProgress >= 1f)
          {
            this.labelStatus.Text = "Progress completed!";
            this.buttonStartProgress.Enabled = true;
          }//end if
        } );
      }//end while
    }
  5. Compile and run the app on the simulator. Tap on the button and watch the progress bar fill.

How it works...

The current value of UIProgressView is represented by its Progress property. Its acceptable value range is always from 0 to 1. So, when we initialize it, we set it to 0 to make sure that the bar is not filled at all. This can be done using the following code:

this.progressView.Progress = 0f;

Since UIProgressView has a specific range, we need to assign the value we want it to be incremented by, depending on the number of items we need to process (in this case, 10) using the following code:

this.incrementBy = 1f / 10f;

In the button's TouchUpInside handler, we disable the button and start our progress through Task from System.Threading.Tasks, as shown in the following code:

this.buttonStartProgress.TouchUpInside += delegate {
  // Disable the button
  this.buttonStartProgress.Enabled = false;
  this.progressView.Progress = 0;
  // Start a progress
  Task.Factory.StartNew(this.StartProgress);
};

In the StartProgress() method, we start a loop that will process the work, which needs to be done. Since the work executes on a separate thread, when we want to make changes to the controls, it must be done on the main UI thread by calling the InvokeOnMainThread method, which accepts a parameter of the NSAction type. An NSAction type parameter can accept anonymous methods as well, as seen in the following code:

this.InvokeOnMainThread(delegate {
  // Advance the progress
  this.progressView.Progress += this.incrementBy;
  currentProgress = this.progressView.Progress;
  // Set the label text
  this.labelStatus.Text = string.Format("Current value: { 0}", Math.Round((double)this.progressView.Progress, 2));
  if (currentProgress >= 1f)
  {
    this.labelStatus.Text = "Progress completed!";
    this.buttonStartProgress.Enabled = true;
  }//end if
});

There's more...

The progress view supports two styles. UIProgressViewStyle.Default (the one that was used in this recipe) and UIProgressViewStyle.Bar. There is absolutely no functionality difference between the two styles, except for appearance. To change the style of the progress view, set its Style property to one of the previously mentioned values.

UIProgressView height

Setting the height of the progress view has no effect, as it is constant for the control. For creating a variable-height progress bar, the UIProgressView class must be subclassed.

See also

  • The Receiving user input with buttons recipe
主站蜘蛛池模板: 巴里| 中阳县| 屯昌县| 桐柏县| 长泰县| 平湖市| 隆尧县| 成武县| 馆陶县| 上林县| 乌兰浩特市| 若尔盖县| 壶关县| 蓝田县| 方正县| 巍山| 夏邑县| 巴中市| 香港| 华阴市| 宣城市| 从江县| 宾阳县| 永胜县| 佳木斯市| 高台县| 徐汇区| 望江县| 兰州市| 铜陵市| 华蓥市| 三穗县| 台南县| 建昌县| 砀山县| 武陟县| 巴南区| 蛟河市| 玉树县| 西畴县| 平果县|