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

[iOS] Fix setting the CurrentItem on CarouselView load #22279

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

rmarinho
Copy link
Member

@rmarinho rmarinho commented May 7, 2024

Description of Change

Since the mappers run when the handler is started and in different order than forms, seems the initial position based on CurrentItem wasn't being set correctly since the mapper for the Position property runs first and overrides it.

We also fix a issue when rotating was not keeping the correct position, since the scroll event was triggered and we want to avoid updating the position till the orientation finishes.

Added a way to know better when we the CollectionViewController is attached or detached from the view hierarchy. So now we can proper call the TearDown and Setup.

Fixes some warnings

Issues Fixed

Fixes #18879

Copilot summary

This pull request contains changes to the CarouselViewHandler and CarouselViewController in the src/Controls/src/Core/Handlers/Items/ directory. The changes primarily focus on improving the handling of carousel view items, including updating the position and visual states of items, managing the carousel loop, and handling device rotation. The changes also include additional null checks and the introduction of new private properties and methods.

Key changes include:

  • CarouselViewHandler.iOS.cs: The MapPosition method has been updated to handle the initial position of the carousel view. The changes ensure that the UpdateFromPosition method is only called when the initial position has been set.

  • CarouselViewController.cs: Several changes have been made to this file, including:

    • The addition of a new Microsoft.Maui.Devices namespace.
    • The introduction of new private properties (_isCenteringItem, _initialOrientation, _isRotating) and the renaming of existing properties (_initialPositionSet to InitialPositionSet, _updatingScrollOffset to _isCenteringItem). [1] [2] [3] [4] [5] [6]
    • The addition of new methods (AttachingToWindow, DetachingFromWindow, OnDisplayInfoChanged) and the updating of existing methods (UpdateItemsSource, UpdateVisibility, UpdateLoop, UpdateFromCurrentItem, UpdateFromPosition, UpdateInitialPosition). These changes improve the handling of carousel view items and device rotation. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]
  • CarouselViewLoopManager: The CenterIfNeeded, Dispose, GetCorrectPositionForCenterItem, GetGoToIndex, CenterVerticallyIfNeeded and CenterHorizontalIfNeeded methods have been updated to include additional null checks. [1] [2] [3] [4] [5]

@rmarinho rmarinho requested a review from a team as a code owner May 7, 2024 18:46
@Eilon Eilon added the area-controls-collectionview CollectionView, CarouselView, IndicatorView label May 7, 2024
@rmarinho rmarinho requested a review from PureWeen May 8, 2024 22:50
jsuarezruiz
jsuarezruiz previously approved these changes May 9, 2024
@@ -23,9 +23,9 @@ protected override void FixtureSetup()
[Category(UITestCategories.CarouselView)]
public async Task CarouselViewSetPosition()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is failing on iOS
image

@@ -17,20 +18,34 @@ public class CarouselViewController : ItemsViewController<CarouselView>
protected readonly CarouselView Carousel;

CarouselViewLoopManager _carouselViewLoopManager;
bool _initialPositionSet;
bool _updatingScrollOffset;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just renamed this one to be more clear

@@ -44,10 +59,14 @@ public override UICollectionViewCell GetCell(UICollectionView collectionView, NS
var correctedIndexPath = NSIndexPath.FromRowSection(cellAndCorrectedIndex.correctedIndex, 0);

if (cell is DefaultCell defaultCell)
{
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing warnings and added {

@rmarinho rmarinho requested a review from PureWeen May 23, 2024 16:44
@@ -249,6 +262,15 @@ void InvalidateMeasureIfContentSizeChanged()
_previousContentSize = contentSize.Value;
}

internal virtual void AttachingToWindow()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we make this private protected instead?

internal override void DettachingFromWindow()
{
base.DettachingFromWindow();
TearDown();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can just outright call TearDown here

Or we need to move some of the cod that's in the ctor into AttachingToWindow

for example this is unsubscrived from

carousel.Scrolled -= CarouselViewScrolled;

Inside of TearDown, but subscribed to in the ctor.

Just because something is detaching from the window, doesn't mean it won't get re-attached.

For example, when a modal is pushed on top of the current screen. The VC below that modal will get unattached.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah , you right, got eager that actually never gets called, let me move the subscribe to the correct place to.

}
}

internal override void DettachingFromWindow()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
internal override void DettachingFromWindow()
internal override void DetachingFromWindow()

{
return;
}

SetPosition(e.CenterItemIndex);

UpdateVisualStates();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to call UpdateVisualStates after the rotation has finished?

@@ -139,13 +139,15 @@ public CarouselItem(int index, string image = null)
Index = index;

if (string.IsNullOrEmpty(image))
Image = "https://picsum.photos/700/300/";
Image = "oasis.jpg";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just fix so we don't use a web image

@@ -82,27 +82,31 @@
CurrentItem="{Binding Selected}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Frame
<Border
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We like Border

@@ -134,6 +134,7 @@ static Microsoft.Maui.Controls.Region.operator !=(Microsoft.Maui.Controls.Region
static Microsoft.Maui.Controls.Region.operator ==(Microsoft.Maui.Controls.Region left, Microsoft.Maui.Controls.Region right) -> bool
static Microsoft.Maui.Controls.Shapes.Matrix.operator !=(Microsoft.Maui.Controls.Shapes.Matrix left, Microsoft.Maui.Controls.Shapes.Matrix right) -> bool
static Microsoft.Maui.Controls.Shapes.Matrix.operator ==(Microsoft.Maui.Controls.Shapes.Matrix left, Microsoft.Maui.Controls.Shapes.Matrix right) -> bool
virtual Microsoft.Maui.Controls.Handlers.Items.CarouselViewHandler.AnimationDuration.get -> double
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure we want to make this public or not,

using CoreGraphics;
using UIKit;

namespace Microsoft.Maui.Controls.Handlers.Items;

internal class MauiCollectionView : UICollectionView
internal class MauiCollectionView : UICollectionView, IUIViewLifeCycleEvents
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows the Controller to know how it can subscribe and cleanup better.

@@ -1,9 +1,11 @@
using System;
using System.Diagnostics.CodeAnalysis;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop this line

this.GetDesiredSizeFromHandler(widthConstraint, heightConstraint);

protected virtual double AnimationDuration => 0.5;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be private for now? open on net9 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-collectionview CollectionView, CarouselView, IndicatorView
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Problem initializing the CurrentItem for the Carousel
4 participants