Many apps display a progress indicator while performing an operation. For example, you’ve likely seen the spinners in iOS apps that let you know the app is performing some kind of work. For more information, see the iOS Human Interface Guidelines article on Progress Indicators.
You can display these in Screenlets by using classes that conform the
ProgressPresenter
protocol.
Liferay Screens includes two such classes:
-
MBProgressHUDPresenter
: Shows a message with a spinner in the middle of the screen. Liferay Screens shows this presenter by default. -
NetworkActivityIndicatorPresenter
: Shows the progress using the iOS network activity indicator. This presenter doesn’t support messages.
This tutorial shows you how to use and create progress presenters, using code from the advanced version of the sample Add Bookmark Screenlet as an example. First, you’ll learn how to use progress presenters.
Using Progress Presenters
The BaseScreenletView
class
contains the default progress presenter functionality. To show a presenter other
than the default MBProgressHUDPresenter
, your View class must therefore
override certain BaseScreenletView
functionality. Follow these steps to do
this:
-
In your View class, override the
BaseScreenletView
methodcreateProgressPresenter
to return an instance of the desired presenter. For example, to useNetworkActivityIndicatorPresenter
in the sample Add Bookmark Screenlet, you must override thecreateProgressPresenter
method inAddBookmarkView_default
to return aNetworkActivityIndicatorPresenter
instance:override func createProgressPresenter() -> ProgressPresenter { return NetworkActivityIndicatorPresenter() }
-
In your View class, override the
BaseScreenletView
propertyprogressMessages
to return the messages you want to use in the presenter. If the presenter doesn’t display messages, then return an empty string. TheprogressMessages
property should return the messages as[String : ProgressMessages]
, whereString
is the Screenlet’s action name.ProgressMessages
is a type alias representing a dictionary where the progress type is the key, and the actual message is the value. The three possible progress types correspond to the Screenlet action’s status:Working
,Failure
, orSuccess
. TheprogressMessages
property therefore lets the presenter display the appropriate message for the Screenlet action’s current status.For example, the following code overrides the
progressMessages
property in Add Bookmark Screenlet’s View class (AddBookmarkView_default
). For each Screenlet action (AddBookmarkAction
andGetTitleAction
), a message (NoProgressMessage
) is assigned to the Screenlet operation’sWorking
status. SinceNoProgressMessage
is an alias for an empty string, this tells the presenter to display no message when the Screenlet attempts to add a bookmark or get a title. Note, however, that the presenter still displays its progress indicator:override var progressMessages: [String : ProgressMessages] { return [ AddBookmarkScreenlet.AddBookmarkAction : [.Working: NoProgressMessage], AddBookmarkScreenlet.GetTitleAction : [.Working: NoProgressMessage], ] }
To display a message, replace
NoProgressMessage
with your message. For example, the following code defines separate messages forWorking
,Success
, andFailure
:override var progressMessages: [String : ProgressMessages] { return [ AddBookmarkScreenlet.AddBookmarkAction : [ .Working: "Saving bookmark...", .Success: "Bookmark saved!", .Failure: "An error occurred saving the bookmark" ], AddBookmarkScreenlet.GetTitleAction : [ .Working: "Getting site title...", .Failure: "An error occurred retrieving the title" ], ] }
Great! Now you know how to use progress presenters. Next, you’ll learn how to create your own.
Creating Progress Presenters
Creating your own progress presenter isn’t as complicated as you might think.
Recall that a presenter in Liferay Screens is a class that conforms the
ProgressPresenter
protocol.
You can create your presenter by conforming this protocol from scratch, or by
extending one of Screens’s existing presenters that already conform this
protocol (MBProgressHUDPresenter
or NetworkActivityIndicatorPresenter
). In
most cases, extending MBProgressHUDPresenter
is sufficient.
For example,
Add Bookmark Screenlet’s AddBookmarkProgressPresenter
extends MBProgressHUDPresenter
to display a different progress indicator for
the Screenlet’s get title action. Use the following steps to create a progress
presenter that extends from an existing presenter. As an example, these steps
extend MBProgressHUDPresenter
to add a progress indicator for the get title
button:
-
In your View’s XIB file, add the activity indicator you want to use. For example, the XIB file in Add Bookmark Screenlet contains an iOS
UIActivityIndicatorView
over the get title button:Figure 1: The updated Add Bookmark Screenlet's XIB file contains a new activity indicator over the get title button.
-
In your View class, create an outlet for the XIB’s new activity indicator. For example, Add Bookmark Screenlet’s View class (
AddBookmarkView_default
) contains an@IBOutlet
for theUIActivityIndicatorView
from the XIB:@IBOutlet weak var activityIndicatorView: UIActivityIndicatorView?
Now you must create your presenter class. You’ll do this here by extending an existing presenter class. Use the following steps to do this:
-
Extend the existing presenter class you want to base your presenter on. Your presenter class must contain properties for your presenter’s activity indicator and any other UI components. It must also contain an initializer that sets these properties. For example,
AddBookmarkProgressPresenter
extendsMBProgressHUDPresenter
and contains properties for the get title button andUIActivityIndicatorView
. Its initializer sets these properties:public class AddBookmarkProgressPresenter: MBProgressHUDPresenter { let button: UIButton? let activityIndicator: UIActivityIndicatorView? public init(button: UIButton?, activityIndicator: UIActivityIndicatorView?) { self.button = button self.activityIndicator = activityIndicator super.init() } ...
-
Implement your presenter’s behavior by overriding the appropriate methods from the presenter class that you’re extending. For example,
AddBookmarkProgressPresenter
overridesMBProgressHUDPresenter
’sshowHUDInView
andhideHUDFromView
methods. The overriddenshowHUDInView
method hides the button and starts animating the activity indicator. The overriddenhideHUDFromView
method stops this animation and restores the button:public override func showHUDInView(view: UIView, message: String?, forInteractor interactor: Interactor) { guard interactor is GetWebTitleInteractor else { return super.showHUDInView(view, message: message, forInteractor: interactor) } button?.hidden = true activityIndicator?.startAnimating() } public override func hideHUDFromView(view: UIView?, message: String?, forInteractor interactor: Interactor, withError error: NSError?) { guard interactor is GetWebTitleInteractor else { return super.hideHUDFromView(view, message: message, forInteractor: interactor, withError: error) } activityIndicator?.stopAnimating() button?.hidden = false } }
Great, that’s it! Now you can use your presenter the same way you would any other.