mirror of
https://github.com/bitwarden/mobile
synced 2025-12-24 12:13:18 +00:00
reset for v2
This commit is contained in:
@@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Foundation;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Core.Views
|
||||
{
|
||||
public class ExtensionSearchDelegate : UISearchBarDelegate
|
||||
{
|
||||
private readonly UITableView _tableView;
|
||||
private CancellationTokenSource _filterResultsCancellationTokenSource;
|
||||
|
||||
public ExtensionSearchDelegate(UITableView tableView)
|
||||
{
|
||||
_tableView = tableView;
|
||||
}
|
||||
|
||||
public override void TextChanged(UISearchBar searchBar, string searchText)
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
Task.Run(() =>
|
||||
{
|
||||
NSRunLoop.Main.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
if(!string.IsNullOrWhiteSpace(searchText))
|
||||
{
|
||||
await Task.Delay(300);
|
||||
if(searchText != searchBar.Text)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_filterResultsCancellationTokenSource?.Cancel();
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
((ExtensionTableSource)_tableView.Source).FilterResults(searchText, cts.Token);
|
||||
_tableView.ReloadData();
|
||||
}
|
||||
catch(OperationCanceledException) { }
|
||||
_filterResultsCancellationTokenSource = cts;
|
||||
});
|
||||
}, cts.Token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.iOS.Core.Models;
|
||||
using Foundation;
|
||||
using Plugin.Settings.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UIKit;
|
||||
using XLabs.Ioc;
|
||||
|
||||
namespace Bit.iOS.Core.Views
|
||||
{
|
||||
public class ExtensionTableSource : UITableViewSource
|
||||
{
|
||||
private const string CellIdentifier = "TableCell";
|
||||
|
||||
private IEnumerable<CipherViewModel> _allItems = new List<CipherViewModel>();
|
||||
protected ICipherService _cipherService;
|
||||
protected ISettings _settings;
|
||||
private bool _accessPremium;
|
||||
private AppExtensionContext _context;
|
||||
private UIViewController _controller;
|
||||
|
||||
public ExtensionTableSource(AppExtensionContext context, UIViewController controller)
|
||||
{
|
||||
_accessPremium = Helpers.CanAccessPremium();
|
||||
_cipherService = Resolver.Resolve<ICipherService>();
|
||||
_settings = Resolver.Resolve<ISettings>();
|
||||
_context = context;
|
||||
_controller = controller;
|
||||
}
|
||||
|
||||
public IEnumerable<CipherViewModel> Items { get; private set; }
|
||||
|
||||
public async Task LoadItemsAsync(bool urlFilter = true, string searchFilter = null)
|
||||
{
|
||||
var combinedLogins = new List<Cipher>();
|
||||
|
||||
if(urlFilter)
|
||||
{
|
||||
var logins = await _cipherService.GetAllAsync(_context.UrlString);
|
||||
if(logins?.Item1 != null)
|
||||
{
|
||||
combinedLogins.AddRange(logins.Item1);
|
||||
}
|
||||
if(logins?.Item2 != null)
|
||||
{
|
||||
combinedLogins.AddRange(logins.Item2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var logins = await _cipherService.GetAllAsync();
|
||||
combinedLogins.AddRange(logins);
|
||||
}
|
||||
|
||||
_allItems = combinedLogins
|
||||
.Where(c => c.Type == App.Enums.CipherType.Login)
|
||||
.Select(s => new CipherViewModel(s))
|
||||
.OrderBy(s => s.Name)
|
||||
.ThenBy(s => s.Username)
|
||||
.ToList() ?? new List<CipherViewModel>();
|
||||
FilterResults(searchFilter, new CancellationToken());
|
||||
}
|
||||
|
||||
public void FilterResults(string searchFilter, CancellationToken ct)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
|
||||
if(string.IsNullOrWhiteSpace(searchFilter))
|
||||
{
|
||||
Items = _allItems.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
searchFilter = searchFilter.ToLower();
|
||||
Items = _allItems
|
||||
.Where(s => s.Name?.ToLower().Contains(searchFilter) ?? false ||
|
||||
(s.Username?.ToLower().Contains(searchFilter) ?? false) ||
|
||||
(s.Uris?.FirstOrDefault()?.Uri?.ToLower().Contains(searchFilter) ?? false))
|
||||
.TakeWhile(s => !ct.IsCancellationRequested)
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<CipherViewModel> TableItems { get; set; }
|
||||
|
||||
public override nint RowsInSection(UITableView tableview, nint section)
|
||||
{
|
||||
return Items == null || Items.Count() == 0 ? 1 : Items.Count();
|
||||
}
|
||||
|
||||
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
if(Items == null || Items.Count() == 0)
|
||||
{
|
||||
var noDataCell = new UITableViewCell(UITableViewCellStyle.Default, "NoDataCell");
|
||||
noDataCell.TextLabel.Text = AppResources.NoItemsTap;
|
||||
noDataCell.TextLabel.TextAlignment = UITextAlignment.Center;
|
||||
noDataCell.TextLabel.LineBreakMode = UILineBreakMode.WordWrap;
|
||||
noDataCell.TextLabel.Lines = 0;
|
||||
return noDataCell;
|
||||
}
|
||||
|
||||
var cell = tableView.DequeueReusableCell(CellIdentifier);
|
||||
|
||||
// if there are no cells to reuse, create a new one
|
||||
if(cell == null)
|
||||
{
|
||||
Debug.WriteLine("BW Log, Make new cell for list.");
|
||||
cell = new UITableViewCell(UITableViewCellStyle.Subtitle, CellIdentifier);
|
||||
cell.DetailTextLabel.TextColor = cell.DetailTextLabel.TintColor = new UIColor(red: 0.47f, green: 0.47f, blue: 0.47f, alpha: 1.0f);
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
public override void WillDisplay(UITableView tableView, UITableViewCell cell, NSIndexPath indexPath)
|
||||
{
|
||||
if(Items == null || Items.Count() == 0 || cell == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var item = Items.ElementAt(indexPath.Row);
|
||||
cell.TextLabel.Text = item.Name;
|
||||
cell.DetailTextLabel.Text = item.Username;
|
||||
}
|
||||
|
||||
public string GetTotp(CipherViewModel item)
|
||||
{
|
||||
string totp = null;
|
||||
if(_accessPremium)
|
||||
{
|
||||
if(item != null && !string.IsNullOrWhiteSpace(item.Totp.Value))
|
||||
{
|
||||
totp = Crypto.Totp(item.Totp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return totp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Core.Views
|
||||
{
|
||||
public class FormEntryTableViewCell : UITableViewCell, ISelectable
|
||||
{
|
||||
public FormEntryTableViewCell(
|
||||
string labelName = null,
|
||||
bool useTextView = false,
|
||||
nfloat? height = null,
|
||||
bool useLabelAsPlaceholder = false)
|
||||
: base(UITableViewCellStyle.Default, nameof(FormEntryTableViewCell))
|
||||
{
|
||||
var descriptor = UIFontDescriptor.PreferredBody;
|
||||
var pointSize = descriptor.PointSize;
|
||||
|
||||
if(labelName != null && !useLabelAsPlaceholder)
|
||||
{
|
||||
Label = new UILabel
|
||||
{
|
||||
Text = labelName,
|
||||
TranslatesAutoresizingMaskIntoConstraints = false,
|
||||
Font = UIFont.FromDescriptor(descriptor, 0.8f * pointSize),
|
||||
TextColor = new UIColor(red: 0.47f, green: 0.47f, blue: 0.47f, alpha: 1.0f)
|
||||
};
|
||||
|
||||
ContentView.Add(Label);
|
||||
}
|
||||
|
||||
if(useTextView)
|
||||
{
|
||||
TextView = new UITextView
|
||||
{
|
||||
TranslatesAutoresizingMaskIntoConstraints = false,
|
||||
Font = UIFont.FromDescriptor(descriptor, pointSize)
|
||||
};
|
||||
|
||||
ContentView.Add(TextView);
|
||||
ContentView.AddConstraints(new NSLayoutConstraint[] {
|
||||
NSLayoutConstraint.Create(TextView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1f, 15f),
|
||||
NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, TextView, NSLayoutAttribute.Trailing, 1f, 15f),
|
||||
NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, TextView, NSLayoutAttribute.Bottom, 1f, 10f)
|
||||
});
|
||||
|
||||
if(labelName != null && !useLabelAsPlaceholder)
|
||||
{
|
||||
ContentView.AddConstraint(
|
||||
NSLayoutConstraint.Create(TextView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, Label, NSLayoutAttribute.Bottom, 1f, 10f));
|
||||
}
|
||||
else
|
||||
{
|
||||
ContentView.AddConstraint(
|
||||
NSLayoutConstraint.Create(TextView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Top, 1f, 10f));
|
||||
}
|
||||
|
||||
if(height.HasValue)
|
||||
{
|
||||
ContentView.AddConstraint(
|
||||
NSLayoutConstraint.Create(TextView, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1f, height.Value));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TextField = new UITextField
|
||||
{
|
||||
TranslatesAutoresizingMaskIntoConstraints = false,
|
||||
BorderStyle = UITextBorderStyle.None,
|
||||
Font = UIFont.FromDescriptor(descriptor, pointSize),
|
||||
ClearButtonMode = UITextFieldViewMode.WhileEditing
|
||||
};
|
||||
|
||||
if(useLabelAsPlaceholder)
|
||||
{
|
||||
TextField.Placeholder = labelName;
|
||||
}
|
||||
|
||||
ContentView.Add(TextField);
|
||||
ContentView.AddConstraints(new NSLayoutConstraint[] {
|
||||
NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1f, 15f),
|
||||
NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, TextField, NSLayoutAttribute.Trailing, 1f, 15f),
|
||||
NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, TextField, NSLayoutAttribute.Bottom, 1f, 10f)
|
||||
});
|
||||
|
||||
if(labelName != null && !useLabelAsPlaceholder)
|
||||
{
|
||||
ContentView.AddConstraint(
|
||||
NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Top, NSLayoutRelation.Equal, Label, NSLayoutAttribute.Bottom, 1f, 10f));
|
||||
}
|
||||
else
|
||||
{
|
||||
ContentView.AddConstraint(
|
||||
NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Top, 1f, 10f));
|
||||
}
|
||||
|
||||
if(height.HasValue)
|
||||
{
|
||||
ContentView.AddConstraint(
|
||||
NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1f, height.Value));
|
||||
}
|
||||
}
|
||||
|
||||
if(labelName != null && !useLabelAsPlaceholder)
|
||||
{
|
||||
ContentView.AddConstraints(new NSLayoutConstraint[] {
|
||||
NSLayoutConstraint.Create(Label, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1f, 15f),
|
||||
NSLayoutConstraint.Create(Label, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Top, 1f, 10f),
|
||||
NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, Label, NSLayoutAttribute.Trailing, 1f, 15f)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public UILabel Label { get; set; }
|
||||
public UITextField TextField { get; set; }
|
||||
public UITextView TextView { get; set; }
|
||||
|
||||
public void Select()
|
||||
{
|
||||
if(TextView != null)
|
||||
{
|
||||
TextView.BecomeFirstResponder();
|
||||
}
|
||||
else if(TextField != null)
|
||||
{
|
||||
TextField.BecomeFirstResponder();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Bit.iOS.Core.Views
|
||||
{
|
||||
public interface ISelectable
|
||||
{
|
||||
void Select();
|
||||
}
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
using CoreGraphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Core.Views
|
||||
{
|
||||
public class PickerTableViewCell : UITableViewCell, ISelectable
|
||||
{
|
||||
private List<string> _items = new List<string>();
|
||||
private int _selectedIndex = 0;
|
||||
|
||||
public PickerTableViewCell(
|
||||
string labelName,
|
||||
nfloat? height = null)
|
||||
: base(UITableViewCellStyle.Default, nameof(PickerTableViewCell))
|
||||
{
|
||||
var descriptor = UIFontDescriptor.PreferredBody;
|
||||
var pointSize = descriptor.PointSize;
|
||||
|
||||
Label = new UILabel
|
||||
{
|
||||
Text = labelName,
|
||||
TranslatesAutoresizingMaskIntoConstraints = false,
|
||||
Font = UIFont.FromDescriptor(descriptor, 0.8f * pointSize),
|
||||
TextColor = new UIColor(red: 0.47f, green: 0.47f, blue: 0.47f, alpha: 1.0f)
|
||||
};
|
||||
|
||||
ContentView.Add(Label);
|
||||
|
||||
TextField = new NoCaretField
|
||||
{
|
||||
BorderStyle = UITextBorderStyle.None,
|
||||
TranslatesAutoresizingMaskIntoConstraints = false,
|
||||
Font = UIFont.FromDescriptor(descriptor, pointSize)
|
||||
};
|
||||
|
||||
var width = (float)UIScreen.MainScreen.Bounds.Width;
|
||||
var toolbar = new UIToolbar(new RectangleF(0, 0, width, 44))
|
||||
{
|
||||
BarStyle = UIBarStyle.Default,
|
||||
Translucent = true
|
||||
};
|
||||
var spacer = new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace);
|
||||
var doneButton = new UIBarButtonItem(UIBarButtonSystemItem.Done, (o, a) =>
|
||||
{
|
||||
var s = (PickerSource)Picker.Model;
|
||||
if(s.SelectedIndex == -1 && Items != null && Items.Count > 0)
|
||||
{
|
||||
UpdatePickerSelectedIndex(0);
|
||||
}
|
||||
TextField.Text = s.SelectedItem;
|
||||
TextField.ResignFirstResponder();
|
||||
});
|
||||
|
||||
toolbar.SetItems(new[] { spacer, doneButton }, false);
|
||||
|
||||
TextField.InputView = Picker;
|
||||
TextField.InputAccessoryView = toolbar;
|
||||
|
||||
ContentView.Add(TextField);
|
||||
|
||||
ContentView.AddConstraints(new NSLayoutConstraint[] {
|
||||
NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1f, 15f),
|
||||
NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, TextField, NSLayoutAttribute.Trailing, 1f, 15f),
|
||||
NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, TextField, NSLayoutAttribute.Bottom, 1f, 10f),
|
||||
NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Top, NSLayoutRelation.Equal, Label, NSLayoutAttribute.Bottom, 1f, 10f),
|
||||
NSLayoutConstraint.Create(Label, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1f, 15f),
|
||||
NSLayoutConstraint.Create(Label, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Top, 1f, 10f),
|
||||
NSLayoutConstraint.Create(ContentView, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, Label, NSLayoutAttribute.Trailing, 1f, 15f)
|
||||
});
|
||||
|
||||
if(height.HasValue)
|
||||
{
|
||||
ContentView.AddConstraint(
|
||||
NSLayoutConstraint.Create(TextField, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1f, height.Value));
|
||||
}
|
||||
|
||||
Picker.Model = new PickerSource(this);
|
||||
}
|
||||
|
||||
public UITextField TextField { get; set; }
|
||||
public UILabel Label { get; set; }
|
||||
public UIPickerView Picker { get; set; } = new UIPickerView();
|
||||
|
||||
public List<string> Items
|
||||
{
|
||||
get { return _items; }
|
||||
set
|
||||
{
|
||||
_items = value;
|
||||
UpdatePicker();
|
||||
}
|
||||
}
|
||||
|
||||
public int SelectedIndex
|
||||
{
|
||||
get { return _selectedIndex; }
|
||||
set
|
||||
{
|
||||
_selectedIndex = value;
|
||||
UpdatePicker();
|
||||
}
|
||||
}
|
||||
|
||||
public string SelectedItem => TextField.Text;
|
||||
|
||||
private void UpdatePicker()
|
||||
{
|
||||
TextField.Text = SelectedIndex == -1 || Items == null ? "" : Items[SelectedIndex];
|
||||
Picker.ReloadAllComponents();
|
||||
if(Items == null || Items.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdatePickerSelectedIndex(SelectedIndex);
|
||||
}
|
||||
|
||||
private void UpdatePickerFromModel(PickerSource s)
|
||||
{
|
||||
TextField.Text = s.SelectedItem;
|
||||
_selectedIndex = s.SelectedIndex;
|
||||
}
|
||||
|
||||
private void UpdatePickerSelectedIndex(int formsIndex)
|
||||
{
|
||||
var source = (PickerSource)Picker.Model;
|
||||
source.SelectedIndex = formsIndex;
|
||||
source.SelectedItem = formsIndex >= 0 ? Items[formsIndex] : null;
|
||||
Picker.Select(Math.Max(formsIndex, 0), 0, true);
|
||||
}
|
||||
|
||||
public void Select()
|
||||
{
|
||||
TextField?.BecomeFirstResponder();
|
||||
}
|
||||
|
||||
private class NoCaretField : UITextField
|
||||
{
|
||||
public NoCaretField() : base(default(CGRect))
|
||||
{ }
|
||||
|
||||
public override CGRect GetCaretRectForPosition(UITextPosition position)
|
||||
{
|
||||
return default(CGRect);
|
||||
}
|
||||
}
|
||||
|
||||
private class PickerSource : UIPickerViewModel
|
||||
{
|
||||
private readonly PickerTableViewCell _cell;
|
||||
|
||||
public PickerSource(PickerTableViewCell cell)
|
||||
{
|
||||
_cell = cell;
|
||||
}
|
||||
|
||||
public int SelectedIndex { get; internal set; }
|
||||
public string SelectedItem { get; internal set; }
|
||||
|
||||
public override nint GetComponentCount(UIPickerView picker)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public override nint GetRowsInComponent(UIPickerView pickerView, nint component)
|
||||
{
|
||||
return _cell.Items != null ? _cell.Items.Count : 0;
|
||||
}
|
||||
|
||||
public override string GetTitle(UIPickerView picker, nint row, nint component)
|
||||
{
|
||||
return _cell.Items[(int)row];
|
||||
}
|
||||
|
||||
public override void Selected(UIPickerView picker, nint row, nint component)
|
||||
{
|
||||
if(_cell.Items.Count == 0)
|
||||
{
|
||||
SelectedItem = null;
|
||||
SelectedIndex = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedItem = _cell.Items[(int)row];
|
||||
SelectedIndex = (int)row;
|
||||
}
|
||||
|
||||
_cell.UpdatePickerFromModel(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Core.Views
|
||||
{
|
||||
public class SliderTableViewCell : UITableViewCell
|
||||
{
|
||||
private string _detailRightSpace = "\t";
|
||||
private int _value;
|
||||
|
||||
public SliderTableViewCell(string labelName, int value, int min, int max)
|
||||
: base(UITableViewCellStyle.Value1, nameof(SwitchTableViewCell))
|
||||
{
|
||||
TextLabel.Text = labelName;
|
||||
DetailTextLabel.TextColor = new UIColor(red: 0.47f, green: 0.47f, blue: 0.47f, alpha: 1.0f);
|
||||
|
||||
Slider = new UISlider
|
||||
{
|
||||
MinValue = min,
|
||||
MaxValue = max,
|
||||
TintColor = new UIColor(red: 0.24f, green: 0.55f, blue: 0.74f, alpha: 1.0f),
|
||||
Frame = new CoreGraphics.CGRect(0, 0, 180, 30)
|
||||
};
|
||||
Slider.ValueChanged += Slider_ValueChanged;
|
||||
Value = value;
|
||||
|
||||
AccessoryView = Slider;
|
||||
}
|
||||
|
||||
private void Slider_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
var newValue = Convert.ToInt32(Math.Round(Slider.Value, 0));
|
||||
bool valueChanged = newValue != Value;
|
||||
|
||||
Value = newValue;
|
||||
|
||||
if(valueChanged)
|
||||
{
|
||||
ValueChanged?.Invoke(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
public UISlider Slider { get; set; }
|
||||
public int Value
|
||||
{
|
||||
get { return _value; }
|
||||
set
|
||||
{
|
||||
_value = value;
|
||||
Slider.Value = value;
|
||||
DetailTextLabel.Text = string.Concat(value.ToString(), _detailRightSpace);
|
||||
}
|
||||
}
|
||||
public event EventHandler ValueChanged;
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Core.Views
|
||||
{
|
||||
public class StepperTableViewCell : UITableViewCell
|
||||
{
|
||||
// Give some space to the right of the detail in between the spacer.
|
||||
// This is a bit of a hack, but I did not see a way to specify a margin on the
|
||||
// detaul DetailTextLabel or AccessoryView
|
||||
private string _detailRightSpace = "\t";
|
||||
private int _value;
|
||||
|
||||
public StepperTableViewCell(string labelName, int value, int min, int max, int increment)
|
||||
: base(UITableViewCellStyle.Value1, nameof(SwitchTableViewCell))
|
||||
{
|
||||
TextLabel.Text = labelName;
|
||||
DetailTextLabel.TextColor = new UIColor(red: 0.47f, green: 0.47f, blue: 0.47f, alpha: 1.0f);
|
||||
|
||||
Stepper = new UIStepper
|
||||
{
|
||||
TintColor = new UIColor(red: 0.47f, green: 0.47f, blue: 0.47f, alpha: 1.0f),
|
||||
MinimumValue = min,
|
||||
MaximumValue = max
|
||||
};
|
||||
Stepper.ValueChanged += Stepper_ValueChanged;
|
||||
Value = value;
|
||||
|
||||
AccessoryView = Stepper;
|
||||
}
|
||||
|
||||
private void Stepper_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
Value = Convert.ToInt32(Stepper.Value);
|
||||
ValueChanged?.Invoke(this, null);
|
||||
}
|
||||
|
||||
public UIStepper Stepper { get; private set; }
|
||||
public int Value
|
||||
{
|
||||
get { return _value; }
|
||||
set
|
||||
{
|
||||
_value = value;
|
||||
Stepper.Value = value;
|
||||
DetailTextLabel.Text = string.Concat(value.ToString(), _detailRightSpace);
|
||||
}
|
||||
}
|
||||
public event EventHandler ValueChanged;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Core.Views
|
||||
{
|
||||
public class SwitchTableViewCell : UITableViewCell
|
||||
{
|
||||
public SwitchTableViewCell(string labelName)
|
||||
: base(UITableViewCellStyle.Default, nameof(SwitchTableViewCell))
|
||||
{
|
||||
TextLabel.Text = labelName;
|
||||
AccessoryView = Switch;
|
||||
|
||||
Switch.ValueChanged += Switch_ValueChanged;
|
||||
}
|
||||
|
||||
private void Switch_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
ValueChanged?.Invoke(this, null);
|
||||
}
|
||||
|
||||
public UISwitch Switch { get; set; } = new UISwitch();
|
||||
public event EventHandler ValueChanged;
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
using Foundation;
|
||||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace Bit.iOS.Core.Views
|
||||
{
|
||||
public class Toast : UIView
|
||||
{
|
||||
private NSTimer _dismissTimer;
|
||||
private NSLayoutConstraint _heightConstraint;
|
||||
private NSLayoutConstraint _leftMarginConstraint;
|
||||
private NSLayoutConstraint _rightMarginConstraint;
|
||||
private NSLayoutConstraint _bottomMarginConstraint;
|
||||
|
||||
public Toast(string text)
|
||||
: base(CoreGraphics.CGRect.FromLTRB(0, 0, 320, 38))
|
||||
{
|
||||
TranslatesAutoresizingMaskIntoConstraints = false;
|
||||
BackgroundColor = UIColor.DarkGray.ColorWithAlpha(0.9f);
|
||||
Layer.CornerRadius = 15;
|
||||
Layer.MasksToBounds = true;
|
||||
|
||||
MessageLabel = new UILabel
|
||||
{
|
||||
TranslatesAutoresizingMaskIntoConstraints = false,
|
||||
TextColor = UIColor.White,
|
||||
Font = UIFont.SystemFontOfSize(14),
|
||||
BackgroundColor = UIColor.Clear,
|
||||
LineBreakMode = UILineBreakMode.WordWrap,
|
||||
TextAlignment = UITextAlignment.Center,
|
||||
Lines = 0,
|
||||
Text = text
|
||||
};
|
||||
|
||||
AddSubview(MessageLabel);
|
||||
|
||||
var hMessageConstraints = NSLayoutConstraint.FromVisualFormat("H:|-5-[messageLabel]-5-|", 0, new NSDictionary(),
|
||||
NSDictionary.FromObjectsAndKeys(new NSObject[] { MessageLabel },
|
||||
new NSObject[] { new NSString("messageLabel") })
|
||||
);
|
||||
|
||||
var vMessageConstraints = NSLayoutConstraint.FromVisualFormat("V:|-0-[messageLabel]-0-|", 0, new NSDictionary(),
|
||||
NSDictionary.FromObjectsAndKeys(new NSObject[] { MessageLabel },
|
||||
new NSObject[] { new NSString("messageLabel") })
|
||||
);
|
||||
|
||||
AddConstraints(hMessageConstraints);
|
||||
AddConstraints(vMessageConstraints);
|
||||
|
||||
AddGestureRecognizer(new UITapGestureRecognizer(() => Dismiss(false)));
|
||||
}
|
||||
|
||||
public bool Dismissed { get; set; }
|
||||
public Action DismissCallback { get; set; }
|
||||
public TimeSpan Duration { get; set; } = TimeSpan.FromSeconds(3);
|
||||
public UILabel MessageLabel { get; set; }
|
||||
public nfloat LeftMargin { get; set; } = 5;
|
||||
public nfloat RightMargin { get; set; } = 5;
|
||||
public nfloat BottomMargin { get; set; } = 5;
|
||||
public nfloat Height { get; set; } = 38;
|
||||
|
||||
public void Show()
|
||||
{
|
||||
if(Superview != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_dismissTimer = NSTimer.CreateScheduledTimer(Duration, x => Dismiss());
|
||||
LayoutIfNeeded();
|
||||
|
||||
var localSuperView = UIApplication.SharedApplication.KeyWindow;
|
||||
if(localSuperView != null)
|
||||
{
|
||||
localSuperView.AddSubview(this);
|
||||
|
||||
_heightConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Height,
|
||||
NSLayoutRelation.GreaterThanOrEqual, null, NSLayoutAttribute.NoAttribute, 1, Height);
|
||||
|
||||
_leftMarginConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Left, NSLayoutRelation.Equal,
|
||||
localSuperView, NSLayoutAttribute.Left, 1, LeftMargin);
|
||||
|
||||
_rightMarginConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Right, NSLayoutRelation.Equal,
|
||||
localSuperView, NSLayoutAttribute.Right, 1, -RightMargin);
|
||||
|
||||
_bottomMarginConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal,
|
||||
localSuperView, NSLayoutAttribute.Bottom, 1, -BottomMargin);
|
||||
|
||||
// Avoid the "UIView-Encapsulated-Layout-Height" constraint conflicts
|
||||
// http://stackoverflow.com/questions/25059443/what-is-nslayoutconstraint-uiview-encapsulated-layout-height-and-how-should-i
|
||||
_leftMarginConstraint.Priority = 999;
|
||||
_rightMarginConstraint.Priority = 999;
|
||||
|
||||
AddConstraint(_heightConstraint);
|
||||
localSuperView.AddConstraint(_leftMarginConstraint);
|
||||
localSuperView.AddConstraint(_rightMarginConstraint);
|
||||
localSuperView.AddConstraint(_bottomMarginConstraint);
|
||||
|
||||
ShowWithAnimation();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Toast needs a keyWindows to display.");
|
||||
}
|
||||
}
|
||||
|
||||
public void Dismiss(bool animated = true)
|
||||
{
|
||||
if(Dismissed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Dismissed = true;
|
||||
_dismissTimer?.Invalidate();
|
||||
_dismissTimer = null;
|
||||
|
||||
if(!animated)
|
||||
{
|
||||
RemoveFromSuperview();
|
||||
DismissCallback?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
SetNeedsLayout();
|
||||
Animate(0.3f, 0, UIViewAnimationOptions.CurveEaseIn, () => { Alpha = 0; }, () =>
|
||||
{
|
||||
RemoveFromSuperview();
|
||||
DismissCallback?.Invoke();
|
||||
});
|
||||
}
|
||||
|
||||
private void ShowWithAnimation()
|
||||
{
|
||||
Alpha = 0;
|
||||
SetNeedsLayout();
|
||||
_bottomMarginConstraint.Constant = -BottomMargin;
|
||||
_leftMarginConstraint.Constant = LeftMargin;
|
||||
_rightMarginConstraint.Constant = -RightMargin;
|
||||
AnimateNotify(0.3f, 0, 0.7f, 5f, UIViewAnimationOptions.CurveEaseInOut, () => { Alpha = 1; }, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user