I'm attempting to Display an UIView on an external monitor in iOS if one is detected. I am able to detected and display a simple UIView using the following code...
public void CheckForExternalDisplay()
{
if (UIScreen.Screens.Length > 1)
{
Mvx.Trace(MvxTraceLevel.Diagnostic, "Multiple screens found");
var externalScreen = UIScreen.Screens[1];
var rect = new RectangleF(new PointF(0, 0), externalScreen.AvailableModes.Max(m => m).Size);
var window = new UIWindow(rect)
{
Screen = UIScreen.Screens[1],
ClipsToBounds = true,
Hidden = false
};
var presenterView = new PresenterView(rect);
window.AddSubview(presenterView);
}
}
This UIView is Very Simple. It contains a UILabel and a RadialProgress View. Most of the heavy lifting to determine what the values should be are already being done on another viewmodel that is updating a view attached to a screen on the phone. I have tried several techniques to try and get the UIView on the external display to update.
- Using MvxMessenger. - I tried passing a message to both a new ViewModel and to the View itself. The new ViewModel received the message only after I created a new instance from the publishing viewmodel. However, I could never intercept messages directly from the view...
- Delay binding and regular fluent binding where the bound viewmodel properties are simply updated from another viewmodel.
- Attempted to bind this View with a viewmodel already associated with another view.
- Wishing in one hand, and crapping in the other... Guess which one filled up first ;)
It's almost as if the UIview (below), isn't being registered/associated with a viewmodel. I'm sure I'm missing something somewhere. As always, I appreciate the help!
public sealed class PresenterView
: MvxView
{
private readonly RadialProgressView _progressView;
private readonly MvxSubscriptionToken _token;
private IMvxMessenger _messenger;
private UILabel _displayLabel;
public PresenterView(RectangleF frame)
: base(frame)
{
Frame = frame;
_messenger = Mvx.Resolve<IMvxMessenger>();
_token = _messenger.Subscribe<DisplayMessage>(OnDisplayMessageReceived);
_displayLabel = new UILabel
{
AdjustsFontSizeToFitWidth = true,
Lines = 1,
LineBreakMode = UILineBreakMode.TailTruncation,
Text = "This is a workout",
Font = UIFont.FromName("rayando", 96f),
BackgroundColor = UIColor.Clear,
PreferredMaxLayoutWidth = Frame.Width - 10,
Frame = new RectangleF(0, 0, Frame.Width - 10, frame.Height / 7),
TextColor = UIColor.White,
TextAlignment = UITextAlignment.Center,
AutoresizingMask = UIViewAutoresizing.All
};
AddSubview(_displayLabel);
_progressView = new RadialProgressView
{
Center = new PointF(Center.X, Center.Y),
MinValue = 0f,
};
AddSubview(_progressView);
this.DelayBind(() =>
{
MvxFluentBindingDescriptionSet<PresenterView, PresenterViewModel> set =
this.CreateBindingSet<PresenterView, PresenterViewModel>();
set.Bind(_progressView).For(pv => pv.Value).To(vm => vm.ClockValue);
set.Bind(_progressView).For(pv => pv.MaxValue).To(vm => vm.MaxProgress);
set.Bind(_workoutLabel).To(vm => vm.DisplayText);
set.Apply();
});
}
private void OnDisplayMessageReceived(DisplayMessage obj)
{
_workoutLabel.Text = obj.Message;
}
}
I do realize that I have included both solutions here. I did try each of them independently.