Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Optional Dates for DateElement, TimeElement, and DateTimeElement #186

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 121 additions & 50 deletions MonoTouch.Dialog/Elements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1701,30 +1701,39 @@ public virtual void ResignFirstResponder (bool animated)
}

public class DateTimeElement : StringElement {
public DateTime DateValue;

public DateTime? DateValue;
public UIDatePicker datePicker;
public event Action<DateTimeElement> DateSelected;
public Action<DateTimeElement> DateSelected;

public bool IsRequired = false;
public bool IsClearing = false;
public bool IsCancelling = false;

protected internal NSDateFormatter fmt = new NSDateFormatter () {
DateStyle = NSDateFormatterStyle.Short
};

public DateTimeElement (string caption, DateTime date) : base (caption)
{
public DateTimeElement(string caption) : this(caption, null) { }

public DateTimeElement(string caption, DateTime? date) : this(caption, date, true) { }

public DateTimeElement (string caption, DateTime? date, bool isRequired)
: base(caption) {

this.IsRequired = isRequired;
DateValue = date;
Value = FormatDate (date);
}

public override UITableViewCell GetCell (UITableView tv)
{
Value = FormatDate (DateValue);
}

public override UITableViewCell GetCell (UITableView tv) {
Value = FormatDate (this.DateValue);
var cell = base.GetCell (tv);
cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
return cell;
}

protected override void Dispose (bool disposing)
{

protected override void Dispose (bool disposing) {
base.Dispose (disposing);
if (disposing){
if (fmt != null){
Expand All @@ -1738,32 +1747,36 @@ protected override void Dispose (bool disposing)
}
}

protected DateTime GetDateWithKind (DateTime dt)
{
if (dt.Kind == DateTimeKind.Unspecified)
return DateTime.SpecifyKind (dt, DateTimeKind.Local);

protected DateTime? GetDateWithKind (DateTime? dt) {
if (!dt.HasValue)
return dt;

if (dt.Value.Kind == DateTimeKind.Unspecified)
return DateTime.SpecifyKind (dt.Value, DateTimeKind.Local);

return dt;
}

public virtual string FormatDate (DateTime dt)
{
public virtual string FormatDate (DateTime? dt) {
if (!dt.HasValue)
return string.Empty;

dt = GetDateWithKind (dt);
return fmt.ToString (dt) + " " + dt.ToLocalTime ().ToShortTimeString ();
return fmt.ToString (dt) + " " + dt.Value.ToLocalTime ().ToShortTimeString ();
}

public virtual UIDatePicker CreatePicker ()
{
public virtual UIDatePicker CreatePicker () {
var date = (DateValue.HasValue) ? DateValue.Value : DateTime.Now;

var picker = new UIDatePicker (RectangleF.Empty){
AutoresizingMask = UIViewAutoresizing.FlexibleWidth,
Mode = UIDatePickerMode.DateAndTime,
Date = DateValue
Date = date
};
return picker;
}

static RectangleF PickerFrameWithSize (SizeF size)
{

static RectangleF PickerFrameWithSize (SizeF size) {
var screenRect = UIScreen.MainScreen.ApplicationFrame;
float fY = 0, fX = 0;

Expand All @@ -1783,33 +1796,35 @@ static RectangleF PickerFrameWithSize (SizeF size)

return new RectangleF (fX, fY, size.Width, size.Height);
}

class MyViewController : UIViewController {
DateTimeElement container;
public DialogViewController PresentingDialogController {get;set;}

public MyViewController (DateTimeElement container)
{
public MyViewController (DateTimeElement container) {
this.container = container;
}

public override void ViewWillDisappear (bool animated)
{
public override void ViewWillDisappear (bool animated) {
base.ViewWillDisappear (animated);
container.DateValue = container.datePicker.Date;

// if we are clearing or cancelling, don't set the date
if (!container.IsCancelling && !container.IsClearing)
container.DateValue = container.datePicker.Date;

if (container.DateSelected != null)
container.DateSelected (container);
}

public override void DidRotate (UIInterfaceOrientation fromInterfaceOrientation)
{
public override void DidRotate (UIInterfaceOrientation fromInterfaceOrientation) {
base.DidRotate (fromInterfaceOrientation);
container.datePicker.Frame = PickerFrameWithSize (container.datePicker.SizeThatFits (SizeF.Empty));
}

public bool Autorotate { get; set; }

public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
{
[Obsolete]
public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation) {
return Autorotate;
}
}
Expand All @@ -1819,42 +1834,98 @@ public override void Selected (DialogViewController dvc, UITableView tableView,
var vc = new MyViewController (this) {
Autorotate = dvc.Autorotate
};

vc.PresentingDialogController = dvc;

datePicker = CreatePicker ();
datePicker.Frame = PickerFrameWithSize (datePicker.SizeThatFits (SizeF.Empty));

vc.View.BackgroundColor = UIColor.Black;
vc.View.AddSubview (datePicker);

// if the date is required, then we don't want to give the user the option to cancel
// or clear the date.
if (!this.IsRequired)
{
if (DateValue.HasValue)
{
// date has a value. allow user to clear the selected date
vc.NavigationItem.RightBarButtonItem = new UIBarButtonItem("Clear", UIBarButtonItemStyle.Done, (s, e) => {

this.IsClearing = true;

ResetDate(dvc);

this.IsClearing = false;
});
}
else
{
// date isn't set. allow user to cancel date selection
vc.NavigationItem.RightBarButtonItem = new UIBarButtonItem(UIBarButtonSystemItem.Cancel, (s, e) => {

this.IsCancelling = true;

ResetDate(dvc);

this.IsCancelling = false;
});
}
}

dvc.ActivateController (vc);
}

private void ResetDate(DialogViewController dvc) {
DateValue = null;
Value = string.Empty;
dvc.ReloadData();

dvc.DeactivateController(true);
}
}

public class DateElement : DateTimeElement {
public DateElement (string caption, DateTime date) : base (caption, date)
{
public DateElement(string caption) : base(caption) {}

public DateElement (string caption, DateTime? date) : base (caption, date) {
fmt.DateStyle = NSDateFormatterStyle.Medium;
}

public override string FormatDate (DateTime dt)
{
return fmt.ToString (GetDateWithKind (dt));
public DateElement (string caption, DateTime? date, bool isRequired) : base(caption, date, isRequired) {
fmt.DateStyle = NSDateFormatterStyle.Medium;
}

public override UIDatePicker CreatePicker ()
{
public override string FormatDate (DateTime? dt) {
string formattedDate = string.Empty;

if (dt.HasValue)
formattedDate = fmt.ToString (dt.Value.ToLocalTime());

return formattedDate;
}

public override UIDatePicker CreatePicker () {
var picker = base.CreatePicker ();
picker.Mode = UIDatePickerMode.Date;
return picker;
}
}

public class TimeElement : DateTimeElement {
public TimeElement (string caption, DateTime date) : base (caption, date)
{
}
public TimeElement(string caption) : base (caption) { }

public override string FormatDate (DateTime dt)
{
return GetDateWithKind (dt).ToLocalTime ().ToShortTimeString ();
public TimeElement (string caption, DateTime? date) : base (caption, date) { }

public TimeElement (string caption, DateTime? date, bool isRequired) : base (caption, date, isRequired) { }

public override string FormatDate (DateTime? dt) {
string formattedDate = string.Empty;

if (dt.HasValue)
formattedDate = dt.Value.ToLocalTime ().ToShortTimeString ();

return formattedDate;
}

public override UIDatePicker CreatePicker ()
Expand Down
6 changes: 5 additions & 1 deletion Sample/DemoElementApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ RootElement CreateRoot ()
},
new Section () {
new EntryElement ("Login", "Your login name", "miguel"),
new EntryElement ("Password", "Your password", "password", true),
new EntryElement ("Password", "Your password", "password", true)
},
new Section () {
new DateElement ("Select Date", DateTime.Now),
new TimeElement ("Select Time", DateTime.Now),
new DateElement ("Date (Optional)", null, false),
new TimeElement ("Time (Optional)", null, false),
},
new Section () {
CreateGeneralSection (),
Expand Down