Skip to content

Commit

Permalink
feat: Allow iOS native visualizer theming
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Aug 4, 2022
1 parent 37f34d9 commit c3f46c1
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ private void OnRefreshCompleted(IRefreshInfoProvider sender, object args)
public void SetAnimations(UIElement refreshVisualizerAnimatableContainer)
{
// TODO: Make visible
//refreshVisualizerAnimatableContainer.Visibility = Visibility.Collapsed;
refreshVisualizerAnimatableContainer.Visibility = Visibility.Collapsed;
}

public void Dispose()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,30 @@
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace Microsoft.UI.Xaml.Controls;

public partial class RefreshContainer : ContentControl
{
private readonly SerialDisposable _refreshSubscription = new SerialDisposable();
private readonly SerialDisposable _nativeScrollViewAttachment = new SerialDisposable();
private NativeRefreshControl _refreshControl = null!;
private NativeRefreshControl? _refreshControl = null;
private UIScrollView? _ownerScrollView = null;

partial void InitializePlatformPartial()
{
this.Loaded += OnLoaded;
this.Unloaded += OnUnloaded;
Loaded += OnLoaded;
Unloaded += OnUnloaded;
}

internal void RequestRefreshPlatform()
{
if (_refreshControl is null)
{
return;
}

if (!_refreshControl.Refreshing)
{
_refreshControl.BeginRefreshing();
Expand All @@ -38,19 +44,23 @@ internal void RequestRefreshPlatform()
}
}

private void OnLoaded(object sender, RoutedEventArgs e) => InitializeRefreshControl();

private void OnUnloaded(object sender, RoutedEventArgs e)
private void OnLoaded(object sender, RoutedEventArgs e)
{
_refreshControl.EndRefreshing();
_refreshSubscription.Disposable = null;
InitializeRefreshControl();
OnRefreshVisualizerChangedPartial();
}

private void OnRefreshControlValueChanged(object? sender, EventArgs e) => OnNativeRefreshingChanged();
private void OnUnloaded(object sender, RoutedEventArgs e) => CleanupRefreshControl();

private bool IsNativeRefreshing => _refreshControl.Refreshing;
private void OnRefreshControlValueChanged(object? sender, EventArgs e) => OnNativeRefreshingChanged();

internal void EndNativeRefreshing() => _refreshControl.EndRefreshing();
internal void EndNativeRefreshing()
{
if (_refreshControl is not null)
{
_refreshControl.EndRefreshing();
}
}

private void InitializeRefreshControl()
{
Expand All @@ -72,17 +82,31 @@ private void InitializeRefreshControl()
_refreshSubscription.Disposable = Disposable.Create(() => _refreshControl.ValueChanged -= OnRefreshControlValueChanged);
}

private void CleanupRefreshControl()
{
if (_refreshControl is not null)
{
_refreshControl.EndRefreshing();
_refreshSubscription.Disposable = null;
}
}

protected override void OnContentChanged(object oldValue, object newValue)
{
base.OnContentChanged(oldValue, newValue);

_nativeScrollViewAttachment.Disposable = null;

AttachToNativeScrollView();
}

private void AttachToNativeScrollView()
{
if (_refreshControl is null)
{
return;
}

// Inject the UIRefreshControl into the first scrollable element found in the hierarchy
if (this.FindFirstChild<UIScrollView>() is { } scrollView)
{
Expand Down Expand Up @@ -121,33 +145,42 @@ private void AttachToNativeScrollView()
}
scrollView.AlwaysBounceVertical = originalBounceSetting;
});
}
}
}

private SerialDisposable _refreshVisualizerSubscriptions = new SerialDisposable();

partial void OnRefreshVisualizerChangedPartial()
{
_refreshVisualizerSubscriptions.Disposable = null;
if (Visualizer is null)

if (_refreshControl is null || Visualizer is null)
{
return;
}

var visualizer = Visualizer;
if (visualizer is NativeRefreshVisualizer)
var compositeDisposable = new CompositeDisposable();
compositeDisposable.Add(visualizer.RegisterDisposablePropertyChangedCallback(RefreshVisualizer.ForegroundProperty, OnVisualizerPropertyChanged));
compositeDisposable.Add(visualizer.RegisterDisposablePropertyChangedCallback(RefreshVisualizer.BackgroundProperty, OnVisualizerPropertyChanged));
_refreshVisualizerSubscriptions.Disposable = compositeDisposable;
}

private void OnVisualizerPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
if (_refreshControl is null || Visualizer is not { } visualizer)
{
return;
}

if (visualizer.Foreground is SolidColorBrush foregroundBrush)
{
InitializeRefreshControl();
_refreshControl.TintColor = foregroundBrush.ColorWithOpacity;
}
else

if (visualizer.Background is SolidColorBrush backgroundBrush)
{
var subviews = _refreshControl.Subviews.ToArray();
foreach (var subview in subviews)
{
subview.RemoveFromSuperview();
}
_refreshControl.AddSubview(visualizer);
visualizer.Bounds = _refreshControl.Bounds;
_refreshVisualizerSubscriptions.Disposable = Disposable.Create(() => visualizer.RemoveFromSuperview());
_refreshControl.BackgroundColor = backgroundBrush.ColorWithOpacity;
}
}
}

0 comments on commit c3f46c1

Please sign in to comment.