diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist
index 9625e105..7c569640 100644
--- a/example/ios/Flutter/AppFrameworkInfo.plist
+++ b/example/ios/Flutter/AppFrameworkInfo.plist
@@ -21,6 +21,6 @@
CFBundleVersion
1.0
MinimumOSVersion
- 11.0
+ 12.0
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index 18c726a3..586e568d 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 50;
+ objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
@@ -136,7 +136,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1300;
+ LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@@ -181,10 +181,12 @@
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
+ "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
@@ -195,6 +197,7 @@
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@@ -280,7 +283,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -359,7 +362,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -406,7 +409,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index f1560181..a00db7a9 100644
--- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,6 +1,6 @@
CADisableMinimumFrameDurationOnPhone
+ UIApplicationSupportsIndirectInputEvents
+
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 950c78c6..3eab8455 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -5,10 +5,13 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:showcaseview/showcaseview.dart';
-void main() => runApp(const MyApp());
+void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
- const MyApp({Key? key}) : super(key: key);
+ MyApp({Key? key}) : super(key: key);
+
+ final GlobalKey _myWidgetKey =
+ GlobalKey();
@override
Widget build(BuildContext context) {
@@ -20,6 +23,15 @@ class MyApp extends StatelessWidget {
debugShowCheckedModeBanner: false,
home: Scaffold(
body: ShowCaseWidget(
+ key: _myWidgetKey,
+ skipShowcaseWidget: Positioned(
+ bottom: 10,
+ left: 10,
+ child: ElevatedButton(
+ child: const Text('Skip Showcase'),
+ onPressed: () => _myWidgetKey.currentState?.dismiss(),
+ ),
+ ),
onStart: (index, key) {
log('onStart: $index, $key');
},
diff --git a/lib/src/showcase.dart b/lib/src/showcase.dart
index 1779f98b..c589feb3 100644
--- a/lib/src/showcase.dart
+++ b/lib/src/showcase.dart
@@ -612,6 +612,7 @@ class _ShowcaseState extends State {
tooltipBackgroundColor: widget.tooltipBackgroundColor,
textColor: widget.textColor,
showArrow: widget.showArrow,
+ staticContainer: showCaseWidgetState.skipShowcaseWidget,
contentHeight: widget.height,
contentWidth: widget.width,
onTooltipTap: _getOnTooltipTap,
diff --git a/lib/src/showcase_widget.dart b/lib/src/showcase_widget.dart
index 16168ba6..c0ce0909 100644
--- a/lib/src/showcase_widget.dart
+++ b/lib/src/showcase_widget.dart
@@ -27,6 +27,12 @@ import '../showcaseview.dart';
class ShowCaseWidget extends StatefulWidget {
final WidgetBuilder builder;
+ /// Creates a button that can be used to skip showCase. For onTap: create a
+ /// global key (final showCaseKey = GlobalKey()
+ /// assign the key to ShowCaseWidget and use it like this:
+ /// onTap: () => showcaseKey.currentState?.dismiss();
+ final Positioned? skipShowcaseWidget;
+
/// Triggered when all the showcases are completed.
final VoidCallback? onFinish;
@@ -83,22 +89,25 @@ class ShowCaseWidget extends StatefulWidget {
/// Enable/disable showcase globally. Enabled by default.
final bool enableShowcase;
- const ShowCaseWidget({
- required this.builder,
- this.onFinish,
- this.onStart,
- this.onComplete,
- this.autoPlay = false,
- this.autoPlayDelay = const Duration(milliseconds: 2000),
- this.enableAutoPlayLock = false,
- this.blurValue = 0,
- this.scrollDuration = const Duration(milliseconds: 300),
- this.disableMovingAnimation = false,
- this.disableScaleAnimation = false,
- this.enableAutoScroll = false,
- this.disableBarrierInteraction = false,
- this.enableShowcase = true,
- });
+ const ShowCaseWidget(
+ {required this.builder,
+ this.onFinish,
+ this.onStart,
+ this.onComplete,
+ this.autoPlay = false,
+ this.autoPlayDelay = const Duration(milliseconds: 2000),
+ this.enableAutoPlayLock = false,
+ this.blurValue = 0,
+ this.scrollDuration = const Duration(milliseconds: 300),
+ this.disableMovingAnimation = false,
+ this.disableScaleAnimation = false,
+ this.enableAutoScroll = false,
+ this.disableBarrierInteraction = false,
+ this.enableShowcase = true,
+ this.skipShowcaseWidget,
+ super.key});
+
+ void dismiss() {}
static GlobalKey? activeTargetWidget(BuildContext context) {
return context
@@ -149,6 +158,8 @@ class ShowCaseWidgetState extends State {
/// Returns value of [ShowCaseWidget.blurValue]
double get blurValue => widget.blurValue;
+ get skipShowcaseWidget => widget.skipShowcaseWidget;
+
@override
void initState() {
super.initState();
diff --git a/lib/src/tooltip_widget.dart b/lib/src/tooltip_widget.dart
index dba238a2..b58c60ce 100644
--- a/lib/src/tooltip_widget.dart
+++ b/lib/src/tooltip_widget.dart
@@ -63,6 +63,7 @@ class ToolTipWidget extends StatefulWidget {
final TextDirection? titleTextDirection;
final TextDirection? descriptionTextDirection;
final double toolTipSlideEndDistance;
+ final Widget? staticContainer;
const ToolTipWidget({
super.key,
@@ -97,6 +98,7 @@ class ToolTipWidget extends StatefulWidget {
this.titleTextDirection,
this.descriptionTextDirection,
this.toolTipSlideEndDistance = 7,
+ this.staticContainer,
});
@override
@@ -365,131 +367,138 @@ class _ToolTipWidgetState extends State
}
if (widget.container == null) {
- return Positioned(
- top: contentY,
- left: _getLeft(),
- right: _getRight(),
- child: ScaleTransition(
- scale: _scaleAnimation,
- alignment: widget.scaleAnimationAlignment ??
- Alignment(
- _getAlignmentX(),
- _getAlignmentY(),
- ),
- child: FractionalTranslation(
- translation: Offset(0.0, contentFractionalOffset as double),
- child: ToolTipSlideTransition(
- position: Tween(
- begin: Offset.zero,
- end: Offset(
- 0,
- widget.toolTipSlideEndDistance * contentOffsetMultiplier,
- ),
- ).animate(_movingAnimation),
- child: Material(
- type: MaterialType.transparency,
- child: Container(
- padding: widget.showArrow
- ? EdgeInsets.only(
- top: paddingTop - (isArrowUp ? arrowHeight : 0),
- bottom: paddingBottom - (isArrowUp ? 0 : arrowHeight),
- )
- : null,
- child: Stack(
- alignment: isArrowUp
- ? Alignment.topLeft
- : _getLeft() == null
- ? Alignment.bottomRight
- : Alignment.bottomLeft,
- children: [
- if (widget.showArrow)
- Positioned(
- left: _getArrowLeft(arrowWidth),
- right: _getArrowRight(arrowWidth),
- child: CustomPaint(
- painter: _Arrow(
- strokeColor: widget.tooltipBackgroundColor!,
- strokeWidth: 10,
- paintingStyle: PaintingStyle.fill,
- isUpArrow: isArrowUp,
+ return Stack(
+ children: [
+ Positioned(
+ top: contentY,
+ left: _getLeft(),
+ right: _getRight(),
+ child: ScaleTransition(
+ scale: _scaleAnimation,
+ alignment: widget.scaleAnimationAlignment ??
+ Alignment(
+ _getAlignmentX(),
+ _getAlignmentY(),
+ ),
+ child: FractionalTranslation(
+ translation: Offset(0.0, contentFractionalOffset as double),
+ child: ToolTipSlideTransition(
+ position: Tween(
+ begin: Offset.zero,
+ end: Offset(
+ 0,
+ widget.toolTipSlideEndDistance * contentOffsetMultiplier,
+ ),
+ ).animate(_movingAnimation),
+ child: Material(
+ type: MaterialType.transparency,
+ child: Container(
+ padding: widget.showArrow
+ ? EdgeInsets.only(
+ top: paddingTop - (isArrowUp ? arrowHeight : 0),
+ bottom:
+ paddingBottom - (isArrowUp ? 0 : arrowHeight),
+ )
+ : null,
+ child: Stack(
+ alignment: isArrowUp
+ ? Alignment.topLeft
+ : _getLeft() == null
+ ? Alignment.bottomRight
+ : Alignment.bottomLeft,
+ children: [
+ if (widget.showArrow)
+ Positioned(
+ left: _getArrowLeft(arrowWidth),
+ right: _getArrowRight(arrowWidth),
+ child: CustomPaint(
+ painter: _Arrow(
+ strokeColor: widget.tooltipBackgroundColor!,
+ strokeWidth: 10,
+ paintingStyle: PaintingStyle.fill,
+ isUpArrow: isArrowUp,
+ ),
+ child: const SizedBox(
+ height: arrowHeight,
+ width: arrowWidth,
+ ),
+ ),
),
- child: const SizedBox(
- height: arrowHeight,
- width: arrowWidth,
+ Padding(
+ padding: EdgeInsets.only(
+ top: isArrowUp ? arrowHeight - 1 : 0,
+ bottom: isArrowUp ? 0 : arrowHeight - 1,
),
- ),
- ),
- Padding(
- padding: EdgeInsets.only(
- top: isArrowUp ? arrowHeight - 1 : 0,
- bottom: isArrowUp ? 0 : arrowHeight - 1,
- ),
- child: ClipRRect(
- borderRadius: widget.tooltipBorderRadius ??
- BorderRadius.circular(8.0),
- child: GestureDetector(
- onTap: widget.onTooltipTap,
- child: Container(
- width: tooltipWidth,
- padding: widget.tooltipPadding,
- color: widget.tooltipBackgroundColor,
- child: Column(
- crossAxisAlignment: widget.title != null
- ? CrossAxisAlignment.start
- : CrossAxisAlignment.center,
- children: [
- if (widget.title != null)
- Padding(
- padding: widget.titlePadding ??
- EdgeInsets.zero,
- child: Text(
- widget.title!,
- textAlign: widget.titleAlignment,
- textDirection:
- widget.titleTextDirection,
- style: widget.titleTextStyle ??
- Theme.of(context)
- .textTheme
- .titleLarge!
- .merge(
- TextStyle(
- color: widget.textColor,
+ child: ClipRRect(
+ borderRadius: widget.tooltipBorderRadius ??
+ BorderRadius.circular(8.0),
+ child: GestureDetector(
+ onTap: widget.onTooltipTap,
+ child: Container(
+ width: tooltipWidth,
+ padding: widget.tooltipPadding,
+ color: widget.tooltipBackgroundColor,
+ child: Column(
+ crossAxisAlignment: widget.title != null
+ ? CrossAxisAlignment.start
+ : CrossAxisAlignment.center,
+ children: [
+ if (widget.title != null)
+ Padding(
+ padding: widget.titlePadding ??
+ EdgeInsets.zero,
+ child: Text(
+ widget.title!,
+ textAlign: widget.titleAlignment,
+ textDirection:
+ widget.titleTextDirection,
+ style: widget.titleTextStyle ??
+ Theme.of(context)
+ .textTheme
+ .titleLarge!
+ .merge(
+ TextStyle(
+ color: widget.textColor,
+ ),
+ ),
+ ),
+ ),
+ Padding(
+ padding: widget.descriptionPadding ??
+ EdgeInsets.zero,
+ child: Text(
+ widget.description!,
+ textAlign:
+ widget.descriptionAlignment,
+ textDirection:
+ widget.descriptionTextDirection,
+ style: widget.descTextStyle ??
+ Theme.of(context)
+ .textTheme
+ .titleSmall!
+ .merge(
+ TextStyle(
+ color: widget.textColor,
+ ),
),
- ),
+ ),
),
- ),
- Padding(
- padding: widget.descriptionPadding ??
- EdgeInsets.zero,
- child: Text(
- widget.description!,
- textAlign: widget.descriptionAlignment,
- textDirection:
- widget.descriptionTextDirection,
- style: widget.descTextStyle ??
- Theme.of(context)
- .textTheme
- .titleSmall!
- .merge(
- TextStyle(
- color: widget.textColor,
- ),
- ),
- ),
+ ],
),
- ],
+ ),
),
),
),
- ),
+ ],
),
- ],
+ ),
),
),
),
),
),
- ),
+ if (widget.staticContainer != null) ...[widget.staticContainer!],
+ ],
);
}
return Stack(