为什么我的 Flutter PageView 在用户选择新的任何权限时会重置 (iOS)

Why is my Flutter PageView resetting when new any permission is selected by a user (iOS)

提问人:Globe 提问时间:11/24/2022 更新时间:11/24/2022 访问量:47

问:

我的应用请求访问照片库、相机、麦克风和位置的权限。每当用户为这些权限提示选择任何选项时,由于某种原因,该选项都会重置并转到第一个选项卡。中没有任何代码调用此函数,并且仅在设置权限后才会发生。我无法弄清楚为什么会这样。CreatePostScreen()PageViewcreate_post_screen.dart

create_post_screen.dart:

class CreatePostScreen extends StatefulWidget {
  const CreatePostScreen({Key? key}) : super(key: key);

  @override
  State<CreatePostScreen> createState() => _CreatePostScreenState();
}

class _CreatePostScreenState extends State<CreatePostScreen> {
  final _locationNameFormKey = GlobalKey<FormState>();
  final _locationNameController = TextEditingController();

  bool _isLoading = false;

  List<String> originalFiles = [];
  List<File> imageFiles = [];

  void selectImages() async {
    final result = await showModalActionSheet(
        context: context,
        title: 'Select Image Source',
        actions: [
          const SheetAction(label: 'Existing Images', key: 'existing'),
          const SheetAction(label: 'New Image', key: 'new')
        ]);

    if (result == 'new' && imageFiles.length < 4) {
      newImage();
    } else if (result == 'existing' && imageFiles.length < 4) {
      existingImages();
    }
  }

  void newImage() async {
    setState(() {
      _isLoading = true;
    });
    final XFile? image =
        await ImagePicker().pickImage(source: ImageSource.camera);
    if (image == null) return;

    cropImages([image.path]);
  }

  void existingImages() async {
    setState(() {
      _isLoading = true;
    });
    final List<XFile>? selectedImages = await ImagePicker().pickMultiImage();
    if (selectedImages == null) return;

    int ableToAdd = 4 - imageFiles.length;

    if (selectedImages.length > ableToAdd) {
      List<XFile>? filesToAdd = selectedImages.sublist(0, ableToAdd);

      List<String> imagePaths = [];

      for (var selectedImage in filesToAdd) {
        imagePaths.add(selectedImage.path);
      }

      cropImages(imagePaths);
    } else {
      List<String> imagePaths = [];

      for (var selectedImage in selectedImages) {
        imagePaths.add(selectedImage.path);
      }

      cropImages(imagePaths);
    }
  }

  void cropImages(List<String> paths) async {
    for (var path in paths) {
      originalFiles.add(path);

      final ImageProperties properties =
          await FlutterNativeImage.getImageProperties(path);

      final int width = properties.width!;
      final int height = properties.height!;

      int imageSize = width < height ? width : height;
      int x = 0;
      int y = 0;

      File imageFile =
          await FlutterNativeImage.cropImage(path, x, y, imageSize, imageSize);

      setState(() {
        int index = originalFiles.indexOf(path);
        imageFiles.insert(index, imageFile);
        _isLoading = false;
      });
    }
  }

  void customCrop(int index) async {
    final fileToCrop = originalFiles[index];

    final croppedFile = await ImageCropper().cropImage(
        sourcePath: fileToCrop,
        aspectRatio: const CropAspectRatio(ratioX: 1, ratioY: 1),
        aspectRatioPresets: [
          CropAspectRatioPreset.square
        ],
        uiSettings: [
          AndroidUiSettings(toolbarTitle: 'Crop Image'),
          IOSUiSettings(title: "Crop Image", showCancelConfirmationDialog: true)
        ]);

    setState(() {
      imageFiles[index] = File(croppedFile!.path);
    });
  }

  Position? position;

  void _determinePosition() async {
    LocationPermission permission;

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
    }

    Position positionResult = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.lowest);
    setState(() {
      position = positionResult;
    });
  }

  pkg.User user = Supabase.auth.currentUser!;

  final postId = DateTime.now().millisecondsSinceEpoch.toString();

  void uploadPost() async {
    if (_locationNameFormKey.currentState!.validate()) {
      _locationNameFormKey.currentState!.save();

      setState(() {
        _isLoading = true;
      });

      String name = _locationNameController.text;

      Location location = Location(
        position!.latitude,
        position!.longitude,
        name,
      );

      List<String> uploadedUrls = [];

      for (var file in imageFiles) {
        String fileName = '${DateTime.now().millisecondsSinceEpoch}_post.png';

        Supabase.storage
            .from('posts')
            .upload('${user.id}/$fileName', supaFile.File(file.path));

        String url = Supabase.storage.from('posts').getPublicUrl('${user.id}/$fileName');

        setState(() {
          uploadedUrls.add(url);
        });

        if (imageFiles.length == uploadedUrls.length) {
          Post post = Post(
            postId,
            uploadedUrls,
            user.id,
            // profile,
            location,
            DateTime.now().millisecondsSinceEpoch,
          );

          print(post);

          try {
            Supabase.db
                .from('posts')
                .insert(post.toJson())
                .then((value) {
              setState(() {
                imageFiles = [];
                originalFiles = [];
                _locationNameController.clear();
                position = null;
                _isLoading = false;
              });
            });
          } catch (error) {
            setState(() {
              _isLoading = false;
            });
            print(error);
          }
        }
      }
    }
  }

  Widget imageItem(int index) {
    File imageFile = imageFiles[index];
    return SizedBox(
      height: 200,
      width: 200,
      child: Card(
        clipBehavior: Clip.hardEdge,
        child: Stack(
          children: [
            Image.file(imageFile, fit: BoxFit.fill),
            Align(
              alignment: Alignment.bottomRight,
              child: Padding(
                padding: const EdgeInsets.all(5),
                child: Row(
                  children: [
                    SizedBox(
                      height: 35,
                      width: 35,
                      child: FittedBox(
                        child: FloatingActionButton(
                          onPressed: () {
                            setState(() {
                              customCrop(index);
                            });
                          },
                          child: const Icon(Icons.edit_outlined),
                        ),
                      ),
                    ),
                    const SizedBox(width: 5),
                    SizedBox(
                      height: 35,
                      width: 35,
                      child: FittedBox(
                        child: FloatingActionButton(
                          onPressed: () {
                            setState(() {
                              imageFiles.removeAt(index);
                              originalFiles.removeAt(index);
                            });
                          },
                          child: const Icon(Icons.delete_forever_sharp),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }

  Widget picker() {
    return imageFiles.isEmpty
        ? GestureDetector(
            onTap: () {
              selectImages();
            },
            child: Center(
              child: Container(
                decoration: BoxDecoration(
                  color: const Color(0xFFd3d8e9),
                  borderRadius: BorderRadius.circular(10),
                ),
                height: 150,
                width: 300,
                child: const Center(
                  child: Text(
                    'Press to add Images - Required',
                    style: TextStyle(color: Colors.red),
                  ),
                ),
              ),
            ),
          )
        : Column(
            children: [
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Container(
                  decoration: BoxDecoration(
                    color: const Color(0xFFd3d8e9),
                    borderRadius: BorderRadius.circular(10),
                  ),
                  child: DragAndDropGridView(
                    physics: const ScrollPhysics(),
                    itemCount: imageFiles.length,
                    gridDelegate:
                        const SliverGridDelegateWithMaxCrossAxisExtent(
                      maxCrossAxisExtent: 200,
                      crossAxisSpacing: 10,
                      mainAxisSpacing: 10,
                    ),
                    itemBuilder: (context, index) {
                      return imageItem(index);
                    },
                    onWillAccept: () {
                      return true;
                    },
                    onReorder: (oldIndex, newIndex) {
                      final temp = imageFiles[newIndex];
                      imageFiles[newIndex] = imageFiles[oldIndex];
                      imageFiles[oldIndex] = temp;
                      setState(() {});
                    },
                  ),
                ),
              ),
            ],
          );
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Scaffold(
          resizeToAvoidBottomInset: true,
          appBar: FloatingAppBar(
            leading: const SizedBox(),
            title: const Text('Create Post',
                style: TextStyle(color: Color(0xFF7157A0), fontSize: 20)),
            actions: [
              if (imageFiles.isEmpty || position == null)
                const Icon(Icons.send_outlined, color: Colors.grey),
              if (imageFiles.isNotEmpty && position != null)
                IconButton(
                  onPressed: () {
                    uploadPost();
                  },
                  icon:
                      const Icon(Icons.send_outlined, color: Color(0xFF7157A0)),
                ),
            ],
          ),
          body: SingleChildScrollView(
            child: Column(
              children: [
                picker(),
                Padding(
                  padding: const EdgeInsets.all(20),
                  child: Form(
                    key: _locationNameFormKey,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        SizedBox(
                          height: 80,
                          width: MediaQuery.of(context).size.width - 40,
                          child: TextFormField(
                            controller: _locationNameController,
                            textInputAction: TextInputAction.done,
                            keyboardType: TextInputType.name,
                            decoration: const InputDecoration(
                              suffix: Icon(Icons.edit_location_outlined,
                                  color: Color(0xFF6C74B4)),
                              labelText: "Location Name",
                              floatingLabelStyle:
                                  TextStyle(color: Color(0xFF697CB4)),
                              enabledBorder: OutlineInputBorder(
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(8)),
                                  borderSide: BorderSide(
                                      color: Color(0xFF6B6FAB), width: 1)),
                              focusedBorder: OutlineInputBorder(
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(8)),
                                  borderSide: BorderSide(
                                      color: Color(0xFF697CB4), width: 1)),
                            ),
                            validator: (name) {
                              if (name == null) {
                                return 'This cannot be left empty';
                              }
                              if (name.length < 4 || name.length > 15) {
                                return 'Must be 4-15 characters';
                              }
                              return null;
                            },
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
                GestureDetector(
                  onTap: () {
                    _determinePosition();
                  },
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      FloatingActionButton(
                        onPressed: () {
                          _determinePosition();
                        },
                        child: const Icon(Icons.location_on_outlined),
                      ),
                      const SizedBox(width: 10),
                      if (position == null)
                        const Text(
                          'Press to add location - Required',
                          style: TextStyle(color: Colors.red),
                        ),
                      if (position != null)
                        Text(
                            'Current location: ${position!.latitude.round()}, ${position!.longitude.round()}')
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
        if (_isLoading)
          const Opacity(
            opacity: 0.8,
            child: ModalBarrier(dismissible: false, color: Colors.black),
          ),
        if (_isLoading)
          const Center(
            child: CircularProgressIndicator(color: Color(0xFFb1bbd8)),
          ),
      ],
    );
  }
}

我感谢任何帮助。

flutter ios-camera ios-permissions ios

评论


答: 暂无答案