Search code examples
iosfluttershadow

Flutter Shadow in IOS


I have a problem with the shadow in a custompaint. apparently the shadow does not take up the entire width of the component due to the blurradius, but it only happens on IOS and not on Android.

First IMAGE:
The Shadow does not take up the entire width (blurradius at 5)

Same shadow with blurradius at 1

in Android its ok. but in IOS was ok before update flutter and rebuild with Xcode.

Someone can help me?

I've try clean flutter and recompile with 2 versions of Xcode 14.2 and 14.3.1.

I think dart:ui package shadow can be corrupt?

I don't know why only goes bad in iOS

this is my code...

class TopPanelClip extends CustomClipper<Path> {
  final height = 50.0;

  @override
  Path getClip(Size size) {
    final Path path = Path();
    path.moveTo(0.0, height);
    path.quadraticBezierTo(size.width / 2, 0.0, size.width, size.height / 2);
    path.lineTo(size.width, size.height);
    path.lineTo(0.0, size.height);
    path.extendWithPath(path, const Offset(0, -2));
    path.close();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper oldClipper) => true;
}

class ClipShadowPath extends StatelessWidget {
  final Shadow shadow;
  final CustomClipper<Path> clipper;
  final Widget child;

  const ClipShadowPath({
    super.key,
    required this.shadow,
    required this.clipper,
    required this.child,
  });

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: _ClipShadowShadowPainter(
        clipper: clipper,
        shadow: shadow,
      ),
      child: ClipPath(clipper: clipper, child: child),
    );
  }
}

class _ClipShadowShadowPainter extends CustomPainter {
  final Shadow shadow;
  final CustomClipper<Path> clipper;

  _ClipShadowShadowPainter({required this.shadow, required this.clipper});

  @override
  void paint(Canvas canvas, Size size) {
    var paint = shadow.toPaint();
    var clipPath = clipper.getClip(size).shift(shadow.offset);
    canvas.drawPath(clipPath, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

and this is my component:

SizedBox(
    width: MediaQuery.of(context).size.width,
    height: 100,
    child: ClipShadowPath(
        shadow: const Shadow(
            blurRadius: 5, offset: Offset(0, -2)),
            clipper: TopPanelClip(),
            child: Container(
            color: ThemeCustom.backgroundColor),
        ),
    )
)

Solution

  • I have found the solution. It's because of the 'impeller render mode' I added the following in my info.plist to fix the problem!

    <key>FLTEnableImpeller</key>
    <false />
    

    That is a bug in flutter by now, they are work in that