Skip to content

Commit 3d8b987

Browse files
committed
xcode issue fixed. project package id changed for ios in xcode
pannablelayout update added with optimizations
1 parent bb85312 commit 3d8b987

File tree

3 files changed

+121
-38
lines changed

3 files changed

+121
-38
lines changed

ios/Runner.xcodeproj/project.pbxproj

+3-4
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@
105105
87253026BE54E668760CED38 /* Pods-RunnerTests.release.xcconfig */,
106106
C73ACC0ECEDB9EFC6B962E15 /* Pods-RunnerTests.profile.xcconfig */,
107107
);
108-
name = Pods;
109108
path = Pods;
110109
sourceTree = "<group>";
111110
};
@@ -478,7 +477,7 @@
478477
"$(inherited)",
479478
"@executable_path/Frameworks",
480479
);
481-
PRODUCT_BUNDLE_IDENTIFIER = com.example.fx2Folder;
480+
PRODUCT_BUNDLE_IDENTIFIER = com.flutterfx.showcase;
482481
PRODUCT_NAME = "$(TARGET_NAME)";
483482
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
484483
SWIFT_VERSION = 5.0;
@@ -661,7 +660,7 @@
661660
"$(inherited)",
662661
"@executable_path/Frameworks",
663662
);
664-
PRODUCT_BUNDLE_IDENTIFIER = com.example.fx2Folder;
663+
PRODUCT_BUNDLE_IDENTIFIER = com.flutterfx.showcase;
665664
PRODUCT_NAME = "$(TARGET_NAME)";
666665
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
667666
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -684,7 +683,7 @@
684683
"$(inherited)",
685684
"@executable_path/Frameworks",
686685
);
687-
PRODUCT_BUNDLE_IDENTIFIER = com.example.fx2Folder;
686+
PRODUCT_BUNDLE_IDENTIFIER = com.flutterfx.showcase;
688687
PRODUCT_NAME = "$(TARGET_NAME)";
689688
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
690689
SWIFT_VERSION = 5.0;

ios/Runner/Info.plist

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<plist version="1.0">
44
<dict>
5+
<key>CADisableMinimumFrameDurationOnPhone</key>
6+
<true/>
57
<key>CFBundleDevelopmentRegion</key>
68
<string>$(DEVELOPMENT_LANGUAGE)</string>
79
<key>CFBundleDisplayName</key>
@@ -24,6 +26,8 @@
2426
<string>$(FLUTTER_BUILD_NUMBER)</string>
2527
<key>LSRequiresIPhoneOS</key>
2628
<true/>
29+
<key>UIApplicationSupportsIndirectInputEvents</key>
30+
<true/>
2731
<key>UILaunchStoryboardName</key>
2832
<string>LaunchScreen</string>
2933
<key>UIMainStoryboardFile</key>
@@ -41,9 +45,5 @@
4145
<string>UIInterfaceOrientationLandscapeLeft</string>
4246
<string>UIInterfaceOrientationLandscapeRight</string>
4347
</array>
44-
<key>CADisableMinimumFrameDurationOnPhone</key>
45-
<true/>
46-
<key>UIApplicationSupportsIndirectInputEvents</key>
47-
<true/>
4848
</dict>
4949
</plist>

lib/circles_selector/CirclesHomeWidget.dart

+114-30
Original file line numberDiff line numberDiff line change
@@ -8,48 +8,132 @@ class CirclesHomeWidget extends StatefulWidget {
88
class _CircleHomeState extends State<CirclesHomeWidget> {
99
@override
1010
Widget build(BuildContext context) {
11-
return Scaffold(
12-
body: ScrollableCircleGrid(),
11+
return const Scaffold(
12+
body: PannableCircleGrid(),
1313
);
1414
}
1515
}
1616

17-
class ScrollableCircleGrid extends StatefulWidget {
17+
class PannableCircleGrid extends StatefulWidget {
18+
const PannableCircleGrid({Key? key}) : super(key: key);
19+
1820
@override
19-
_ScrollableCircleGridState createState() => _ScrollableCircleGridState();
21+
_PannableCircleGridState createState() => _PannableCircleGridState();
2022
}
2123

22-
class _ScrollableCircleGridState extends State<ScrollableCircleGrid> {
23-
int? selectedIndex;
24+
class _PannableCircleGridState extends State<PannableCircleGrid> {
25+
Offset _offset = Offset.zero;
26+
int? _selectedIndex;
27+
final double _circleSize = 60;
28+
final double _spacing = 20;
29+
final int _columns = 1000; // Arbitrary large number for columns
2430

2531
@override
2632
Widget build(BuildContext context) {
27-
return GridView.builder(
28-
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
29-
crossAxisCount: 5,
30-
childAspectRatio: 1,
33+
return GestureDetector(
34+
onPanUpdate: (details) {
35+
setState(() {
36+
_offset += details.delta;
37+
});
38+
},
39+
child: ClipRect(
40+
child: CustomPaint(
41+
painter: CircleGridPainter(
42+
offset: _offset,
43+
circleSize: _circleSize,
44+
spacing: _spacing,
45+
selectedIndex: _selectedIndex,
46+
columns: _columns,
47+
),
48+
child: GestureDetector(
49+
onTapUp: (details) {
50+
_handleTap(details.localPosition);
51+
},
52+
),
53+
),
3154
),
32-
itemBuilder: (context, index) {
55+
);
56+
}
57+
58+
void _handleTap(Offset tapPosition) {
59+
int col =
60+
((tapPosition.dx - _offset.dx) / (_circleSize + _spacing)).floor();
61+
int row =
62+
((tapPosition.dy - _offset.dy) / (_circleSize + _spacing)).floor();
63+
int index = row * _columns + col;
64+
65+
setState(() {
66+
_selectedIndex = (_selectedIndex == index) ? null : index;
67+
});
68+
}
69+
}
70+
71+
class CircleGridPainter extends CustomPainter {
72+
final Offset offset;
73+
final double circleSize;
74+
final double spacing;
75+
final int? selectedIndex;
76+
final int columns;
77+
78+
CircleGridPainter({
79+
required this.offset,
80+
required this.circleSize,
81+
required this.spacing,
82+
required this.columns,
83+
this.selectedIndex,
84+
});
85+
86+
@override
87+
void paint(Canvas canvas, Size size) {
88+
final paint = Paint()
89+
..color = Colors.grey
90+
..style = PaintingStyle.fill;
91+
92+
final selectedPaint = Paint()
93+
..color = Colors.white
94+
..style = PaintingStyle.fill;
95+
96+
final textPainter = TextPainter(
97+
textDirection: TextDirection.ltr,
98+
);
99+
100+
final startCol = (-offset.dx / (circleSize + spacing)).floor() - 1;
101+
final endCol = ((size.width - offset.dx) / (circleSize + spacing)).ceil();
102+
final startRow = (-offset.dy / (circleSize + spacing)).floor() - 1;
103+
final endRow = ((size.height - offset.dy) / (circleSize + spacing)).ceil();
104+
105+
for (int row = startRow; row <= endRow; row++) {
106+
for (int col = startCol; col <= endCol; col++) {
107+
final circleOffset = Offset(
108+
col * (circleSize + spacing) + offset.dx,
109+
row * (circleSize + spacing) + offset.dy,
110+
);
111+
112+
int index = row * columns + col;
33113
bool isSelected = selectedIndex == index;
34-
return GestureDetector(
35-
onTap: () {
36-
setState(() {
37-
selectedIndex = isSelected ? null : index;
38-
});
39-
},
40-
child: AnimatedContainer(
41-
duration: Duration(milliseconds: 300),
42-
margin: EdgeInsets.all(isSelected ? 8 : 4),
43-
decoration: BoxDecoration(
44-
shape: BoxShape.circle,
45-
color: isSelected ? Colors.white : Colors.grey,
46-
),
47-
child: Center(
48-
child: Text('Friend $index'),
49-
),
50-
),
114+
115+
canvas.drawCircle(
116+
circleOffset,
117+
isSelected ? circleSize * 0.6 : circleSize * 0.5,
118+
isSelected ? selectedPaint : paint,
51119
);
52-
},
53-
);
120+
121+
textPainter.text = TextSpan(
122+
text: '$index',
123+
style: TextStyle(
124+
color: isSelected ? Colors.black : Colors.white, fontSize: 12),
125+
);
126+
textPainter.layout();
127+
textPainter.paint(
128+
canvas,
129+
circleOffset - Offset(textPainter.width / 2, textPainter.height / 2),
130+
);
131+
}
132+
}
54133
}
134+
135+
@override
136+
bool shouldRepaint(covariant CircleGridPainter oldDelegate) =>
137+
offset != oldDelegate.offset ||
138+
selectedIndex != oldDelegate.selectedIndex;
55139
}

0 commit comments

Comments
 (0)