• 0

[C#/WPF] Animate a UserControl


Question

Hello gang,

I am learning WPF and I need to animate a UserControl that has been added during runtime

XAML


<Window x:Class="BediaNVMain.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="515" Width="1598" ShowInTaskbar="False" Topmost="True" WindowState="Maximized" WindowStyle="None" Background="#FF001900" xmlns:my="clr-namespace:BediaMenu;assembly=BediaMenu">
<Canvas Name="BediaCanvas"
<Grid Name="BediaGrid" Loaded="BediaGrid_Loaded">
</Grid>
</Canvas>
</Window>
[/CODE]

C# code to add UserControl (BediaMenu.BMenu)

[CODE]
var bmnuBediaMenu = new BediaMenu.BMenu();
bmnuBediaMenu.Margin = new Thickness(40, MenuTop, 40, 20);
bmnuBediaMenu.MenuText = MenuTitle;
bmnuBediaMenu.Height = this.MenuSize;
bmnuBediaMenu.Width = this.ActualWidth - 80;
this.BediaGrid.Children.Add(bmnuBediaMenu);
[/CODE]

I attempted to use the code from this page: http://stackoverflow.com/questions/4214155/wpf-easiest-way-to-move-image-to-x-y-programmatically But when it gets to the last line; story.Begin(this); it errors with this statement: "'BediaMenu' name cannot be found in the name scope of 'BediaNVMain.MainWindow'." I have attempted several options... but with no success.

Any thoughts?

Link to comment
https://www.neowin.net/forum/topic/1051139-cwpf-animate-a-usercontrol/
Share on other sites

Recommended Posts

  • 0
  On 13/01/2012 at 17:25, ~Johnny said:

It looks like you're not actually telling it to look for this instance of the object - you should be passing in the variable name of the object instead (in this case, bmnuBediaMenu), not BediaMenu.

I am using bmnuBediaMenu... I should have included the code that I affected from that url. So here it is (feel free to slap me and tell me; "NO dumbass, it's.....)


Storyboard story = new Storyboard();
DoubleAnimation dbWidth = new DoubleAnimation();
dbWidth.From = bmnuBediaMenu.Width;
dbWidth.To = 600;
dbWidth.Duration = new Duration(TimeSpan.FromSeconds(2.25));
DoubleAnimation dbHeight = new DoubleAnimation();
dbHeight.From = bmnuBediaMenu.Height;
dbHeight.To = 400;
dbHeight.Duration = dbWidth.Duration;
story.Children.Add(dbWidth);
Storyboard.SetTargetName(dbWidth, bmnuBediaMenu.Name);
Storyboard.SetTargetProperty(dbWidth, new PropertyPath(MediaElement.WidthProperty));
story.Children.Add(dbHeight);
Storyboard.SetTargetName(dbHeight, bmnuBediaMenu.Name);
Storyboard.SetTargetProperty(dbHeight, new PropertyPath(MediaElement.HeightProperty));
DoubleAnimation dbCanvasX = new DoubleAnimation();
dbCanvasX.From = 0;
dbCanvasX.To = 5;
dbCanvasX.Duration = new Duration(TimeSpan.FromSeconds(.25));
DoubleAnimation dbCanvasY = new DoubleAnimation();
dbCanvasY.From = 0;
dbCanvasY.To = 5;
dbCanvasY.Duration = dbCanvasX.Duration;
story.Children.Add(dbCanvasX);
Storyboard.SetTargetName(dbCanvasX, bmnuBediaMenu.Name);
Storyboard.SetTargetProperty(dbCanvasX, new PropertyPath(Canvas.LeftProperty));
story.Children.Add(dbCanvasY);
Storyboard.SetTargetName(dbCanvasY, bmnuBediaMenu.Name);
Storyboard.SetTargetProperty(dbCanvasY, new PropertyPath(Canvas.TopProperty));
story.Begin(this);
[/CODE]

  • 0
  On 13/01/2012 at 17:32, ~Johnny said:

You haven't given your menu a name? Set bmnuBediaMenu.Name to something (You're trying to set a storyboard target to this name, but it hasn't got one)

You were correct, I did not give it a name. (now called "FirstMenu") However adding a name did not affect the error. I now get: 'FirstMenu' name cannot be found in the name scope of 'BediaNVMain.MainWindow'.

I FEEL like it has something to do with the Storyboard not properly linking into the location of bmnuBediaMenu... but I do not really know.

btw: Thanks for your time.

I thought I should post the entire function, just in case


private void LoadBediaMenu(string MenuTitle, double MenuTop)
{
try
{
var bmnuBediaMenu = new BediaMenu.BMenu();

bmnuBediaMenu.Margin = new Thickness(40, MenuTop, 40, 20);
bmnuBediaMenu.Name = "FirstMenu";
bmnuBediaMenu.MenuText = MenuTitle;
bmnuBediaMenu.Height = this.MenuSize;
bmnuBediaMenu.Width = this.ActualWidth - 80;
this.BediaGrid.Children.Add(bmnuBediaMenu);


Storyboard story = new Storyboard();
DoubleAnimation dbWidth = new DoubleAnimation();
dbWidth.From = bmnuBediaMenu.Width;
dbWidth.To = 600;
dbWidth.Duration = new Duration(TimeSpan.FromSeconds(2.25));
DoubleAnimation dbHeight = new DoubleAnimation();
dbHeight.From = bmnuBediaMenu.Height;
dbHeight.To = 400;
dbHeight.Duration = dbWidth.Duration;
story.Children.Add(dbWidth);
Storyboard.SetTargetName(dbWidth, bmnuBediaMenu.Name);
Storyboard.SetTargetProperty(dbWidth, new PropertyPath(MediaElement.WidthProperty));
story.Children.Add(dbHeight);
Storyboard.SetTargetName(dbHeight, bmnuBediaMenu.Name);
Storyboard.SetTargetProperty(dbHeight, new PropertyPath(MediaElement.HeightProperty));
DoubleAnimation dbCanvasX = new DoubleAnimation();
dbCanvasX.From = 0;
dbCanvasX.To = 5;
dbCanvasX.Duration = new Duration(TimeSpan.FromSeconds(.25));
DoubleAnimation dbCanvasY = new DoubleAnimation();
dbCanvasY.From = 0;
dbCanvasY.To = 5;
dbCanvasY.Duration = dbCanvasX.Duration;
story.Children.Add(dbCanvasX);
Storyboard.SetTargetName(dbCanvasX, bmnuBediaMenu.Name);
Storyboard.SetTargetProperty(dbCanvasX, new PropertyPath(Canvas.LeftProperty));
story.Children.Add(dbCanvasY);
Storyboard.SetTargetName(dbCanvasY, bmnuBediaMenu.Name);
Storyboard.SetTargetProperty(dbCanvasY, new PropertyPath(Canvas.TopProperty));
story.Begin(this);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
[/CODE]

  • 0
  On 13/01/2012 at 17:45, articuno1au said:

this.BediaGrid.Children.Add(bmnuBediaMenu);

I think you need to look another layer deeper.

EDIT:: It's entirely possible I am misreading this. I'm struggling with your var names D:

Do you mean, for example, this line


Storyboard.SetTargetName(dbCanvasX, bmnuBediaMenu.Name);
[/CODE]

Should be like this:

[CODE]
Storyboard.SetTargetName(dbCanvasX, this.BediaGrid.bmnuBediaMenu.Name);
[/CODE]

The problem with that is the code cannot find the bmnuBediaMenu as during compile time it is not within the Grid.

  • 0

Yeah, you will need to obtain it with something like this.

BediaMenu temp = new BediaMenu();
temp = BediaGrid.GetChild(<type/name>);[/CODE]

Sorry, it's pretty shoddy pseudocode.

Then operate on temp. That's the best way to do it I can think of.

Is there any reason you are adding it programatically instead of "hard coding" it?

  • 0
  On 13/01/2012 at 17:51, articuno1au said:

Yeah, you will need to obtain it with something like this.

BediaMenu temp = new BediaMenu();
temp = BediaGrid.GetChild(<type name="">);[/CODE]

Sorry, it's pretty shoddy pseudocode.

Then operate on temp. That's the best way to do it I can think of.

Is there any reason you are adding it programatically instead of "hard coding" it?

I will look into getting the object reference (thanks, no worries about the pcode)

The reason that the menus are loaded programatically as opposed to in the XAML is that the number of menus varies based on the user's screen height and the height of the menu (which can be changed by the user) If you want to see where this is going you can see version 1 of Bedia at my site http://www.blissgig.com/display.aspx?id=13

  • 0

Looks interesting..

God damn @ the new IPB text editor. It keeps changing code bits into stupid things D:

The only painful thing about working with programatically generated interfaces is you have to .GetObject/Child/BananaPeel to do anything.

EDIT:: Congrats on evolving from VB.net to C# :p You feel more manly already don't you? :p

  • 0
  On 13/01/2012 at 18:00, articuno1au said:

EDIT:: Congrats on evolving from VB.net to C# :p You feel more manly already don't you? :p

I starting playing with c# back in 2001, but since all my jobs since then have been with VB there has not been a big deal to change over. I tend to be tech-agnostic. Whatever offers the better job, that's what I care about. There are some things I miss about VB, ie: the Intelisense does not work as well.. but nbd.

I tried this code, but still the same error ('FirstMenu' name cannot be found in the name scope of 'BediaNVMain.MainWindow'.) What dumba$$ thing am I doing?


private void LoadBediaMenu(string MenuTitle, double MenuTop)
{
try
{
var bmnuBediaMenu = new BediaMenu.BMenu();

bmnuBediaMenu.Margin = new Thickness(40, MenuTop, 40, 20);
bmnuBediaMenu.Name = "FirstMenu";
bmnuBediaMenu.MenuText = MenuTitle;
bmnuBediaMenu.Height = this.MenuSize;
bmnuBediaMenu.Width = this.ActualWidth - 80;
this.BediaGrid.Children.Add(bmnuBediaMenu);

foreach (UIElement element in this.BediaCanvas.Children)
{
if (element is Grid)
{
Grid grd = element as Grid;
foreach (UIElement mnuElement in grd.Children)
{
if (mnuElement is BediaMenu.BMenu)
{
BediaMenu.BMenu bMenu = mnuElement as BediaMenu.BMenu;
if (bMenu.Name == "FirstMenu")
{
//Animation Test 02
Storyboard story = new Storyboard();
DoubleAnimation dbWidth = new DoubleAnimation();
dbWidth.From = bMenu.Width;
dbWidth.To = 600;
dbWidth.Duration = new Duration(TimeSpan.FromSeconds(2.25));
DoubleAnimation dbHeight = new DoubleAnimation();
dbHeight.From = bMenu.Height;
dbHeight.To = 400;
dbHeight.Duration = dbWidth.Duration;
story.Children.Add(dbWidth);
Storyboard.SetTargetName(dbWidth, bMenu.Name);
Storyboard.SetTargetProperty(dbWidth, new PropertyPath(MediaElement.WidthProperty));
story.Children.Add(dbHeight);
Storyboard.SetTargetName(dbHeight, bMenu.Name);
Storyboard.SetTargetProperty(dbHeight, new PropertyPath(MediaElement.HeightProperty));
DoubleAnimation dbCanvasX = new DoubleAnimation();
dbCanvasX.From = 0;
dbCanvasX.To = 5;
dbCanvasX.Duration = new Duration(TimeSpan.FromSeconds(2.25));
DoubleAnimation dbCanvasY = new DoubleAnimation();
dbCanvasY.From = 0;
dbCanvasY.To = 5;
dbCanvasY.Duration = dbCanvasX.Duration;
story.Children.Add(dbCanvasX);
Storyboard.SetTargetName(dbCanvasX, bMenu.Name);
Storyboard.SetTargetProperty(dbCanvasX, new PropertyPath(Canvas.LeftProperty));
story.Children.Add(dbCanvasY);
Storyboard.SetTargetName(dbCanvasY, bMenu.Name);
Storyboard.SetTargetProperty(dbCanvasY, new PropertyPath(Canvas.TopProperty));
story.Begin(this);
}

}
}
}
}

}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
[/CODE]

  • 0

Sorry, at this point my advice is to put a break point in and see if the code is getting hit.

I can't see anything obvious >.<

EDIT:: I'd also start iterating children as of:


Grid grd = element as Grid;
foreach (UIElement mnuElement in grd.Children)
[/CODE]

Just in case there is some of odd "Typing" issue.

  • 0

I'm not entirely sure, but try changing story.Begin(this) to just story.Begin();

It shouldn't matter whether it's there at compile time or not - by the time you run the code it should already be in the visual tree at the correct position, so it should make no difference (although depending on the hardware and complexity of the menu, you may want to attach the storyboard creation to the loaded event of the UserControl, just to be safe and make sure it's properly in the visual tree)

  • 0
  On 13/01/2012 at 18:21, articuno1au said:

Sorry, at this point my advice is to put a break point in and see if the code is getting hit.

I can't see anything obvious >.<

EDIT:: I'd also start iterating children as of:


Grid grd = element as Grid;
foreach (UIElement mnuElement in grd.Children)
[/CODE]

Just in case there is some of odd "Typing" issue.

I step though the entire function, and it runs fine, finds the correct Menu, I have a titlebar menu already set, so the code correctly ignores that.

  On 13/01/2012 at 18:22, ~Johnny said:

I'm not entirely sure, but try changing story.Begin(this) to just story.Begin();

It shouldn't matter whether it's there at compile time or not - by the time you run the code it should already be in the visual tree at the correct position, so it should make no difference

I tried that, similar error; "No applicable name scope exists to resolve the name 'FirstMenu'."

The issue with compile time is that if I use

[CODE]
Storyboard.SetTargetName(dbCanvasX, this.BediaGrid.bmnuBediaMenu.Name);
[/CODE]

The code will not run/compile as the object "bmnuBediaMenu" does not exist within the grid. Or am I missing what you are trying to say?

Again, thank you both for your time. Happy Friday the 13th!

VS screams

  • 0

If the menu successfully gets added to the Grid without crashing (this is without the storyboard code), then everything should be fine. You are adding the menu to your grid in your code, so it will exist in the visual tree when you run the code.

For what it's worth I've used this code in my own projects to some success for animating across X axis (and applicable for Y)


/// <summary>
/// Slide animate a FrameworkElement along the X axis
/// </summary>
/// <param name="x">The FrameworkElement to animate</param>
/// <param name="df">Starting X offset of the animation</param>
/// <param name="dt">Ending X offset of the animation</param>
/// <param name="time">The length of the animation in milliseconds</param>
internal static void AnimateElementTransformX(FrameworkElement x, Double df, Double dt, Int32 time)
{
try
{
DoubleAnimation ani = new DoubleAnimation();
ani.From = (!(Double.IsNaN(df))) ? df : x.RenderTransform.Value.OffsetX;
ani.To = 0;
ani.Duration = new Duration(TimeSpan.FromMilliseconds(time));
var sb = new Storyboard();
sb.Children.Add(ani);
TranslateTransform tt2 = new TranslateTransform();
App.Current.MainWindow.RegisterName("TT2", tt2);
x.RenderTransform = tt2;
Storyboard.SetTargetName(ani, "TT2");
Storyboard.SetTargetProperty(ani, new PropertyPath(TranslateTransform.XProperty));
x.Resources.Add("SB);
sb.Begin();
x.Resources.Remove("SB");
App.Current.MainWindow.UnregisterName("TT2");
}
catch { /** Null Target Animation Error **/ }
}
[/CODE]

Which you'd use something like

[font=courier new,courier,monospace]AnimateElementTransformX(bmnuBediaMenu, 50, 0, 100);[/font]

for a 100ms animation, animating it from a 50px offset to it's original position

Though I'd probably find it easier to create the animation in XAML in the UserControl, and then set the animation to trigger when the UserControl is loaded.

  • 0

The menu adds to the canvas/grid fine... and I had tried a some code similar to yours (thanks!) but it still errors on sb.Begin() with: 'TT2' name cannot be found in the name scope of 'BediaMenu.BMenu'." I changed the bmnuBediaMenu.Name = "TT2" in the original code to insure that that was not the issue and yet....

I feel that the answer is really close, but I am missing it. (obviously)

  • 0

Ahh, I think I might have spotted it.

Is it that you are calling story.Begin(this) on LoadBediaMenu rather than LoadedBediaMenu (OnLoad/OnLoaded)?

I can't tell where you have registered the event, but that could do it I think >.<

  • 0
  On 13/01/2012 at 18:45, James Rose said:

The menu adds to the canvas/grid fine... and I had tried a some code similar to yours (thanks!) but it still errors on sb.Begin() with: 'TT2' name cannot be found in the name scope of 'BediaMenu.BMenu'." I changed the bmnuBediaMenu.Name = "TT2" in the original code to insure that that was not the issue and yet....

I feel that the answer is really close, but I am missing it. (obviously)

I *think* (I'm not sure, can't remember what I was thinking when I wrote it :p), but this *might* work for you.


/// <summary>
/// Slide animate a FrameworkElement along the X axis
/// </summary>
/// <param name="x">The FrameworkElement to animate</param>
/// <param name="df">Starting X offset of the animation</param>
/// <param name="dt">Ending X offset of the animation</param>
/// <param name="time">The length of the animation</param>
/// <param name="p">The parent element to register the transform in</param>
internal static void AnimateElementTransformX(FrameworkElement x, Double df, Double dt, Int32 time, FrameworkElement p)
{
try
{
DoubleAnimation ani = new DoubleAnimation();
ani.From = (!(Double.IsNaN(df))) ? df : x.RenderTransform.Value.OffsetX;
ani.To = 0;
ani.Duration = new Duration(TimeSpan.FromMilliseconds(time));
var sb = new Storyboard();
sb.Children.Add(ani);
TranslateTransform tt2 = new TranslateTransform();
p.RegisterName("TT2", tt2);
x.RenderTransform = tt2;
Storyboard.SetTargetName(ani, "TT2");
Storyboard.SetTargetProperty(ani, new PropertyPath(TranslateTransform.XProperty));
x.Resources.Add("SB);
sb.Begin();
x.Resources.Remove("SB");
p.UnregisterName("TT2");
}
catch { /** Null Target Animation Error **/ }
}
[/CODE]

The difference here is you also have to pass in the element's parent element at the end as well, so something like AnimateElementTransformX(bmnuBediaMenu, 50, 0, 100, BediaGrid) might work. Although for some reason I never actaully used this code over the previous method, so it may not actually work. (Again, I must prefer to write them in XAML)

  • 0

Johnny,

Thanks, and that was what I was attempting to do (had not gotten there yet, so thanks!) but still an error on sb.Begin

'TT2' name cannot be found in the name scope of 'BediaMenu.BMenu'.

-----------------

Art,

The function "LoadBediaMenu" adds one menu and then calls Johnny's function "AnimateElementTransformX" where the BediaMenu is to be moved. Is this an issue? Can't I add a control and then move it within the same function? (even though "technically" these are two functions)

  • 0

I think it's to do with the object not being fully initiated.

I was just working my way through: http://msdn.microsoft.com/en-us/library/ms752312.aspx

They've bound the animation separately from the animation start. This is (I think) irrelevant. The interesting thing to note is when the story.Begin(this) is called. I think you need to delay the Begin call until after the object is fully loaded.

I think the best part of my idea is all it "costs" is binding the start to Loaded rather than Load. 2 seconds to test, 2 seconds to undo >.<

  • 0
  On 13/01/2012 at 19:24, articuno1au said:

I think it's to do with the object not being fully initiated.

I was just working my way through: http://msdn.microsof...y/ms752312.aspx

They've bound the animation separately from the animation start. This is (I think) irrelevant. The interesting thing to note is when the story.Begin(this) is called. I think you need to delay the Begin call until after the object is fully loaded.

I think the best part of my idea is all it "costs" is binding the start to Loaded rather than Load. 2 seconds to test, 2 seconds to undo >.<

I believe you're taking about this piece from that link


private void myRectangleLoaded(object sender, RoutedEventArgs e)
{
myStoryboard.Begin(this);
}
[/CODE]

I have been reviewing that page for a few days and saw that. However it does not matter. For example I have this code that is called when I click on the Titlebar

[CODE]
private void Titlebar_MouseDown(object sender, MouseButtonEventArgs e)
{
if (bLoaded == false)
{
LoadBediaMenu("Fade In and Out 2", 500);
bLoaded = true;
}
else
{
AnimateElementTransformX(bmnuBediaMenu, 0, 30, 100, BediaGrid);
}
}
[/CODE]

The BediaMenu is completely loaded and yet I still get the same error: 'TT2' name cannot be found in the name scope of 'BediaMenu.BMenu'.

Very strange, very interesting.... and more than a bit annoying. One of my laws of development is that the longer it takes to find a solution to an issue, the more simple/straight-forward it is, and therefore the dumber you will feel when you figure it out. This one is going to make me feel REAL stupid, I just know it.

  • 0

I'd say skip all that, go with this in the XAML of the UserControl:


<Usercontrol ....
x:name="bmnuMenu"
...>
<UserControl.Resources>
<Storyboard x:Key="Entry">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="bmnuMenu">
<EasingDoubleKeyFrame KeyTime="0" Value="30"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<UserControl.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</UserControl.RenderTransform>
<UserControl.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Entry}"/>
</EventTrigger>
</UserControl.Triggers>[/CODE]

You probably don't need all those transform groups, but that should work.

Edit: Stupid thing has messed up the casings.

  • 0
  On 13/01/2012 at 19:42, ~Johnny said:

I'd say skip all that, go with this in the XAML of the UserControl:


<usercontrol ....="" x:name="UserControl">
<usercontrol.resources>
<storyboard x:key="Entry">
<doubleanimationusingkeyframes storyboard.targetproperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" storyboard.targetname="UserControl">
<easingdoublekeyframe keytime="0" value="30">
<easingdoublekeyframe keytime="0:0:0.3" value="0">
</easingdoublekeyframe></easingdoublekeyframe></doubleanimationusingkeyframes>
</storyboard>
</usercontrol.resources>
<usercontrol.rendertransform>
<transformgroup>
<scaletransform>
<skewtransform>
<rotatetransform>
<translatetransform>
</translatetransform></rotatetransform></skewtransform></scaletransform></transformgroup>
</usercontrol.rendertransform>
<usercontrol.triggers>
<eventtrigger routedevent="FrameworkElement.Loaded">
<beginstoryboard storyboard="{StaticResource Entry}">
</beginstoryboard></eventtrigger>
</usercontrol.triggers>
[/CODE]

You probably don't need all those transform groups, but that should work.

I'd love to just use XAML, but the number of menus varies based on the user's screen height and the height of the menu (customizable) so until runtime I do not know how many I will need. I REALLY wish I could know ahead of time, that would make my life SO much easier.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • I guess companies have numbers that don't necessarily match your assessment.
    • I agree that all capabilities of the card should be reviewed, but there is a very important difference between reviewing what multiframe generation is and does for you, and simply claiming a card has 200+ FPS just because MFG is on. You are probably well aware that frame generation is getting a lot of hate, which I feel like is partly unfair to it. However, Nvidia has used frame generation to tell outright lies about their products, most notably claiming that a 5070 is as powerful as a 4090. Its easy to hate something when it is being used to make dishonest statements like that. I'm not a big fan of the popular term "fake frames" just because I feel like it is overly negative, but I do think it is important to make some kind of distinction between game engine frames and filler frames.
    • What is the replacement or successor to it right now?
    • iPhone 17 Pro Max could have the biggest battery ever on an iPhone by Devesh Beri Leaks around how the iPhone 17 Pro lineup is going to look may have left fans hesitant about what Apple is planning for its next flagship, but not every rumor paints a gloomy picture. In fact, one area where the iPhone 17 Pro Max could truly stand out is its battery; rumors say it is to have the biggest battery ever seen in an iPhone. Let's be honest, battery life has long been a weak point for iPhones. No matter how efficient Apple's A-series chipsets are said to be, users often find their devices running out of juice quicker than expected. Much of the blame could be put on the relatively small battery sizes Apple has chosen over the years, especially when compared to the competition. Many rival brands now give their large-screen devices, those with displays bigger than 6.5 inches, batteries of at least 5000mAh. In contrast, Apple's largest iPhones have lagged behind in this department, with the iPhone 16 Pro Max coming in at 4676mAh. It seems like it is set to change with the iPhone 17 Pro Max, as a prominent leaker, Instant Digital, revealed that the battery of the iPhone 17 Pro Max will finally reach the 5000mAh mark. How big a change would it be? To put it in perspective, the iPhone 17 Pro Max's battery would be about 6.9% bigger than the iPhone 16 Pro Max, 13.1% more than the iPhone 15 Pro Max, and 15.7% more than the iPhone 14 Pro Max. If these rumors are accurate, the iPhone 17 Pro Max may finally address one of the most common complaints about Apple's flagship devices, but then again, Apple would still be lagging as most of the brands, specially the Chinese ones have already moved to the battery limits of 6000mAh and some have even touched 7000mAh. This rumor comes after the observation that Apple's struggles with AI may prompt it to transition Siri to either OpenAI or Anthropic's AI capabilities. Image source: Digit.in
  • Recent Achievements

    • Week One Done
      Devesh Beri earned a badge
      Week One Done
    • Week One Done
      956400 earned a badge
      Week One Done
    • First Post
      loose_observer earned a badge
      First Post
    • Week One Done
      BeeJay_Balu earned a badge
      Week One Done
    • Week One Done
      filminutz earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      465
    2. 2
      ATLien_0
      159
    3. 3
      +FloatingFatMan
      149
    4. 4
      Nick H.
      66
    5. 5
      +thexfile
      62
  • Tell a friend

    Love Neowin? Tell a friend!