- iOS Development with Xamarin Cookbook
- Dimitris Tavlikos
- 629字
- 2025-04-04 21:43:38
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.
- Add the following
using
directives in theProgressAppViewController
class file:using System.Drawing; using System.Threading; using System.Threading.Tasks;
- Add the following fields in the class:
UILabel labelStatus; UIButton buttonStartProgress; UIProgressView progressView; float incrementBy = 0f;
- 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);
- 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 }
- 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.
See also
- The Receiving user input with buttons recipe