【iOS开发】(四)react Native第三方组件五个20240419-20

react native 外的 第三方组件

目录标题

  • react native 外的 第三方组件
      • (一)与rn核心组件的使用步骤区别:
      • (二)第三方组件概览
          • 1 WebView
          • 2 Picker
          • 3 Swiper
          • 4 AsyncStorage
          • 5 Geolocation
          • 6 Camera
      • (三)详细学习
        • 1 WebView
          • CocoaPods
          • 1 URL
          • 2 html
        • 2 Picker
        • 3 swiper
        • 4 AsyncStorage
          • 1 异步存储的特点:
          • 2 异步存储 使用场景举例:
          • 3 AsyncStorage 详解
            • 1. setItem数据存储
            • 2. getItem读取数据
            • 3. removeItem删除数据
            • 4. 更新数据
            • 5. 清空所有数据
            • 6. 获取所有键
            • 7. 批量获取多个键值
            • 8. 批量存储多个键值
            • 9. 批量删除多个键
            • 10 mergeItem 合并键值对
            • 11 useAsyncStorage
            • 注意
            • 封装 Async storage
          • 4 geolocation获取定位

(一)与rn核心组件的使用步骤区别:

  1. 需单独安装
  2. 配置
  3. 使用

(二)第三方组件概览

1 WebView
  • 描述: WebView 相当于一个内置浏览器,它允许你在应用内部显示网页,从而集成外部网站或在线资源。
2 Picker
  • 描述: Picker 是一个下拉选择框组件,用于在应用中提供一个简洁的界面,让用户可以从一组选项中选择一个。
3 Swiper
  • 描述: Swiper 组件用于展示轮播效果,非常适用于引导页面或展示图片集,支持手势滑动和自动播放功能。
4 AsyncStorage
  • 描述: AsyncStorage 是一个简单的、异步的、持久化的键值对存储系统,用于在本地保存少量数据,适合存储用户偏好或应用状态。
5 Geolocation
  • 描述: Geolocation 组件用于获取设备的当前位置信息。它可以提供精确的地理坐标,支持实时位置跟踪。
6 Camera
  • 描述: Camera 组件允许应用调用设备的摄像头拍照或录像。它可以用于添加图像上传或现场视频捕捉的功能。

以上每个组件都在现代应用开发中扮演着重要的角色,提供了丰富的功能和用户体验。

(三)详细学习

1 WebView
CocoaPods

CocoaPods 是一个用于管理 iOS 和 macOS 应用开发中 Objective-C 和 Swift 语言项目的依赖项管理工具。它支持自动化地处理外部库的集成问题,帮助开发者更高效地管理项目中使用的各种第三方库和框架。

主要特点:
自动化依赖管理:CocoaPods 可以自动解析项目所需的第三方库依赖关系,并确保所有依赖项都兼容并且最新。
简化安装过程:通过编写一个名为 Podfile 的配置文件,你可以声明项目需要哪些第三方库。执行 pod install 命令后,CocoaPods 会自动下载并集成这些库。
版本控制:CocoaPods 允许你指定依赖库的版本,帮助避免因库更新带来的潜在问题,同时也可以轻松更新到新版本。
开放和共享:它利用一个名为 Specs 的中央仓库来管理各种公共的依赖库描述文件,任何人都可以向其贡献自己的库。
使用场景:
开发者在创建和维护 iOS 或 macOS 应用时,往往需要使用第三方库来增加新功能或者减少重复的工作

在这里插入图片描述

1 URL
// ESLint 规则禁用说明:关闭了关于 React Native 中内联样式的 ESLint 警告。
/* eslint-disable react-native/no-inline-styles */

// React 组件和基础组件导入被注释掉,因为它们在这段代码中未使用。
// 如果你需要使用 Text, StyleSheet, View 等组件,可以取消注释。
// import {Text, StyleSheet, View} from 'react-native';

// 导入 React 默认库,以及 React 组件基类。
import React, {Component} from 'react';

// 从 react-native-webview 包导入 WebView 组件。
// WebView 组件用于在你的应用中显示一个全功能的浏览器。
import {WebView} from 'react-native-webview';

// 定义 Index 类,这个类继承自 Component,使其成为一个 React 组件。
class MyWeb extends Component {
  // render 方法是每个 React 组件必须实现的方法,它定义了组件的 UI。
  render() {
    // 返回 WebView 组件,用于加载并显示给定的 uri。
    // uri 设为 'https://m.baidu.com',WebView 将会加载并显示这个网址的内容。
    return (
      // WebView 组件的样式被设置为 marginTop: 20,这意味着它会在顶部留出 20 像素的空间。
      // 这个内联样式只是为了快速示例,通常推荐使用 StyleSheet.create 来创建样式。
      <WebView source={{uri: 'https://m.baidu.com'}} style={{marginTop: 20}} />
    );
  }
}

// 将 Index 组件导出为模块的默认导出。
// 这使得其他文件可以通过 import Index from '<path>' 的形式导入 Index 组件。
export default MyWeb

2 html
    
import React, { Component } from 'react';

import { WebView } from 'react-native-webview';

// 定义 Index 类,这个类继承自 Component,使其成为一个 React 组件。
class MyWeb extends Component {
  // render 方法是每个 React 组件必须实现的方法,它定义了组件的 UI。
  render() {
    // 返回 WebView 组件,用于加载并显示给定的 uri。
    return (
      <WebView
        source={{
          html: "<h1 >erewfg<h1/>"
        }}
        style={{ marginTop: 120 }} />
    );
  }
}

// 将 Index 组件导出为模块的默认导出。
// 这使得其他文件可以通过 import Index from '<path>' 的形式导入 Index 组件。
export default MyWeb


import React from 'react';
import { WebView } from 'react-native-webview';

const YourComponent = () => {
  const htmlContent = `

    <h1>21345678<h1/>
`;

  return (
    <WebView
      originWhitelist={['*']}
      source={{ html: htmlContent }}
      style={{ marginTop: 100 }} // 顶部留出 100 像素的空间。
    />
  );
};

export default YourComponent;


2 Picker

在这里插入图片描述


/*prettier/prettier */

/* eslint-disable react-native/no-inline-styles */
import {View, StyleSheet} from 'react-native';
import React, {Component} from 'react';
import {Picker} from '@react-native-picker/picker';

export default class Index extends Component {
  constructor() {
    super();
    this.state = {
      color: 'white',
    };
  }
  render() {
    return (
      <View style={[styles.container, {backgroundColor: this.state.color}]}>
        <Picker
          mode="dropdown" // 只在安卓下有效
          selectionColor="red"
          selectedValue={this.state.color}
          style={{height: 50, width: 160, fontSize: 15}}
          onValueChange={(itemValue, itemIndex) => {
            this.setState({color: itemValue});
          }}>
          <Picker.Item label="白色" value="white" />
          <Picker.Item label="红色" value="red" />
        </Picker>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});


在这里插入图片描述

3 swiper

安装

在这里插入图片描述

在 React Native 中使用 Swiper 组件时,通常是通过第三方库,如 react-native-swiper,来实现轮播图或滑动视图功能。这个组件提供了多种属性来定制其行为和外观。以下是一些 react-native-swiper 的常用属性:

loop: 布尔值,决定轮播是否循环。设置为 true 时,轮播会无限循环。
autoplay: 布尔值,控制是否自动播放轮播图。当设置为 true 时,轮播图会自动滚动。
showsPagination: 布尔值,用于控制是否显示分页指示器。默认为 true。
index: 初始加载组件时显示的滑动块的索引,从0开始。
horizontal: 布尔值,设置滑动方向。默认为 true,表示水平方向滑动。设置为 false 则变为垂直滑动。
onIndexChanged: 函数,当轮播图切换时调用。提供当前索引作为参数。
loadMinimal: 布尔值,当设置为 true 时,仅加载当前项和缓冲项,以节省内存和减少加载时间。
paginationStyle: 对象,自定义分页指示器的样式。
activeDotColor: 字符串,定义活动点的颜色(当前视图的分页点)。
dotColor: 字符串,定义非活动点的颜色。


import { StyleSheet, Image, Dimensions, ScrollView, View, Text } from 'react-native';
import React, { Component } from 'react';
import Swiper from 'react-native-swiper';

export default class index extends Component {
  render() {
    return (
      <ScrollView style={{ flex: 1 }}>
        <Swiper autoplay={true} showsButtons={true} style={styles.wrapper}>
          <View style={styles.slide}>
            <Image
              style={styles.slideImage}
              source={require('./images/1.jpg')}
            />
            <Text> </Text>
            <Text style={styles.slideText}
            > 宝贝玩滑梯</Text>
          </View>
          <View style={styles.slide}>
            <Image
              style={styles.slideImage}
              source={require('./images/2.jpg')}
            />


            <Text> </Text>
            <Text style={styles.slideText}
            > 宝贝笑</Text>


          </View>
          <View style={styles.slide}>
            <Image
              style={styles.slideImage}
              source={require('./images/3.jpg')}
            />

            <Text> </Text>
            <Text style={styles.slideText}
            > 宝贝回家</Text>
          </View>

        </Swiper>


        <Text> </Text>
        <Text style={styles.slideText}>《 宝贝春游日记》</Text>

        <Text
        >
          

        </Text>
        <Text>          今天是春季的一个阳光明媚的日子,我们一家三口决定去郊外游玩,感受春天的气息。
        </Text>

        <Text>     清晨,天空湛蓝,阳光温暖,我和爸爸妈妈兴奋地出发了。


          我们的目的地是市郊的一个大公园。到了公园,首先映入眼帘的是满园的绿色和点缀其中的五颜六色的花朵。我们在花丛中漫步,我尤其喜欢那些漂亮的郁金香和茂盛的樱花。花儿们在春风中轻轻摇曳,好像在对我们说“欢迎”。</Text>
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  wrapper: {
    height: 250, // 增加了整个Swiper的高度
  },
  slide: {
    flex: 1,
    justifyContent: 'center', // 确保内容垂直居中
    alignItems: 'center', // 确保内容水平居中
  },
  slideImage: {
    height: 200,
    width: Dimensions.get('window').width,
    resizeMode: 'cover', // 确保图片覆盖整个可用宽度
  },
  slideText: {
    color: 'red', // 将文本颜色设置为白色

    fontSize: 16, // 增加字体大小以提高可读性
    padding: 5, // 添加一些内边距
  }
});

4 AsyncStorage

在React Native中,AsyncStorage是一个简单、异步、持久的Key-Value存储系统。它用于在设备上保存数据,使得数据即使在应用重启后也依然可以使用。

异步存储是一种数据存储方法,其操作(如读取、写入或删除数据)不会立即完成,而是在未来某个时刻完成,这些操作不会阻塞程序的继续执行。这意味着程序可以继续运行其他任务,而不必等待存储操作的完成。这种方式特别适用于需要处理大量数据或者在后台进行数据操作的应用,因为它可以提高应用的响应速度和性能。

1 异步存储的特点:
  • 非阻塞性:异步操作允许用户界面或程序继续响应其他任务,而不是等待数据存储操作完成。
  • 基于回调或Promise:异步存储通常使用回调函数或Promise来处理操作完成后的结果,这样可以在数据操作完成后执行特定的代码。
  • 适用于Web和移动应用:在Web开发中,异步存储可以通过浏览器的Web Storage API、IndexedDB等技术实现。在移动开发中,如在React Native中,可以使用AsyncStorage库来实现。
2 异步存储 使用场景举例:
  • Web应用中的数据缓存:例如,一个网页可以异步地将用户的浏览记录存储到本地,不影响用户继续浏览其他页面。
  • 移动应用中的用户偏好设置:移动应用可以异步地存储用户的设置选择,如主题色或布局偏好,而不干扰用户的正常交互。

异步存储的使用提高了应用的效率和用户体验,尤其是在处理大量数据或在后台执行复杂任务时。

因此,类似于数据库理解 ,在React Native中,AsyncStorage主要是增删改查功能。

3 AsyncStorage 详解

https://react-native-async-storage.github.io/async-storage/docs/install/ 安装配置指导及学习手册

在这里插入图片描述

1. setItem数据存储
  • setItem: 异步保存键值对。当需要存储用户设置或待持久保存的数据时使用。
  • 用法: AsyncStorage.setItem('key', 'value')
import AsyncStorage from '@react-native-async-storage/async-storage';

const storeData = async (value) => {
  try {
    await AsyncStorage.setItem('@storage_Key', value)
  } catch (e) {
    // 保存错误
  }
}

setObjectValue = async (value) => {
  try {
  
    const jsonValue = JSON.stringify(value)
     
    await AsyncStorage.setItem('key', jsonValue)
  } catch(e) {
    // save error
  }

  console.log('Done.')
}
2. getItem读取数据
  • getItem: 异步读取存储的值。
  • 用法: AsyncStorage.getItem('key')
getMyStringValue = async () => {
  try {
    return await AsyncStorage.getItem('@key')
  } catch(e) {
    // read error
  }

  console.log('Done.')
}
getMyObject = async () => {
  try {
    const jsonValue = await AsyncStorage.getItem('@key')
    return jsonValue != null ? JSON.parse(jsonValue) : null
  } catch(e) {
    // read error
  }

  console.log('Done.')
}
3. removeItem删除数据
  • removeItem: 异步删除存储的键值对。
  • 用法: AsyncStorage.removeItem('key')
removeValue = async () => {
  try {
    await AsyncStorage.removeItem('@MyApp_key')
  } catch(e) {
    // remove error
  }

  console.log('Done.')
}
4. 更新数据
  • 数据更新: 可通过重复使用setItem方法使用新值覆盖旧值。
  • 用法: AsyncStorage.setItem('key', 'new value')
5. 清空所有数据
  • clear: 异步清除所有AsyncStorage中的数据。慎用,因为这将删除所有当前存储的数据。
  • 用法: AsyncStorage.clear()
6. 获取所有键
  • getAllKeys: 异步获取所有存储的键。
  • 用法: AsyncStorage.getAllKeys()
7. 批量获取多个键值
  • multiGet: 异步同时获取多个键对应的值。
  • 用法: AsyncStorage.multiGet(['key1', 'key2'])
8. 批量存储多个键值
  • multiSet: 异步同时设置多个键值对。
  • 用法: AsyncStorage.multiSet([['key1', 'value1'], ['key2', 'value2']])
9. 批量删除多个键
  • multiRemove: 异步同时删除多个键。
  • 用法: AsyncStorage.multiRemove(['key1', 'key2'])
10 mergeItem 合并键值对

mergeItem
mergeItem(key, value) 接受一个键和一个新的 JSON 字符串化的值,然后将这个新值合并到已经存在的值中。如果原先的值和新值都是 JSON 对象,mergeItem 会深层次地合并这两个对象的字段。如果键不存在,它会像 setItem 一样工作。
下面这个例子展示了如何用 mergeItem 更新嵌套的 JSON 对象中的一部分,而不是替换整个对象。这对于开发中的设置或用户首选项管理非常有用,可以避免读取整个对象、手动更新它然后再保存回去的繁琐流程。

请注意,AsyncStorage 的使用建议限制在轻量级数据存储,对于复杂或大量数据的存储,可能需要考虑更高级的数据库解决方案。

import AsyncStorage from '@react-native-async-storage/async-storage';

// 假设你已经有了这样一个存储的对象
const storeData = async () => {
  const initialUserSettings = JSON.stringify({
    volume: 10,
    theme: 'dark'
  });
  try {
    await AsyncStorage.setItem('@UserSettings', initialUserSettings);
  } catch (error) {
    // 错误处理
  }
};

// 现在,假设我们只想更新主题,而不影响音量设置
const updateUserSettings = async () => {
  const updatedSettings = JSON.stringify({
    theme: 'light'
  });
  try {
    await AsyncStorage.mergeItem('@UserSettings', updatedSettings);
  } catch (error) {
    // 错误处理
  }
};

// 读取数据以验证更新
const readUserSettings = async () => {
  try {
    const result = await AsyncStorage.getItem('@UserSettings');
    const settings = result ? JSON.parse(result) : null;
    if (settings) {
      console.log(settings); // 应输出: { volume: 10, theme: 'light' }
    }
  } catch (error) {
    // 错误处理
  }
};

// 初始化数据
storeData().then(() => {
  // 更新数据
  updateUserSettings().then(() => {
    // 读取更新后的数据
    readUserSettings();
  });
});

11 useAsyncStorage

useAsyncStorage返回一个对象,该对象公开了允许与存储值交互的所有方法。

import React, { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { useAsyncStorage } from '@react-native-async-storage/async-storage';

export default function App() {
  const [value, setValue] = useState('value');
  const { getItem, setItem } = useAsyncStorage('@storage_key');

  const readItemFromStorage = async () => {
    const item = await getItem();
    setValue(item);
  };

  const writeItemToStorage = async newValue => {
    await setItem(newValue);
    setValue(newValue);
  };

  useEffect(() => {
    readItemFromStorage();
  }, []);

  return (
    <View style={{ margin: 40 }}>
      <Text>Current value: {value}</Text>
      <TouchableOpacity
        onPress={() =>
          writeItemToStorage(
            Math.random()
              .toString(36)
              .substr(2, 5)
          )
        }
      >
        <Text>Update value</Text>
      </TouchableOpacity>
    </View>
  );
}
注意
  • AsyncStorage操作通常返回一个Promise,因此可以使用async/await或.then来处理异步操作的结果。
  • 在React Native 0.59及以上版本,AsyncStorage已从核心组件中移除,推荐使用社区维护的@react-native-community/async-storage

综合示例一

import { Text, StyleSheet, View, Button } from 'react-native'
import React, { Component } from 'react'
import AsyncStorage from '@react-native-async-storage/async-storage'

export default class index extends Component {
  storeData = async (value) => {
    try {
      await AsyncStorage.setItem('mytest', value)
    } catch (e) {
      // 保存错误
    }
  }
  getData = async () => {
    try {
      const value = await AsyncStorage.getItem('mytest')
      //保持key都是 mytest 
      if (value !== null) {
        alert(value)
      }
    } catch (e) {
      // read error
    }

    console.log('Done.')
  }

  render() {
    return (
      <View styles={[styles.container]}>
        <Text></Text>
        <Text></Text>

        {/* /在storeData中传入参数  */}
        <Button title='存储' onPress={this.storeData('Hello wdm')} />
        <Button title='获取' onPress={this.getData } />

      </View>
    )
  }
}

const styles = StyleSheet.create({

  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'

  }

})
封装 Async storage

四个模块

set(key,value)

delete(key)|clear()

update(key,value)

get(key)

Storage.js

import AsyncStorage from '@react-native-async-storage/async-storage'
//写一个具有增删改查功能的模块 并封装成一个类  
class Storage {

  /**
   * 添加数据
   * @param {string} key 
   * @param {mixed} value 
   * @returns {Promise}
   */

  //写具体的set添加数据的方法  set
  //set 里面有key  value两个参数 

  static set(key, value) {
    //具体的执行逻辑

    return AsyncStorage.setItem(key, JSON.stringify(value))
    // 注意 此处JSON 为大写
    //在保存对象或数组到 AsyncStorage 而setItem时,由于 AsyncStorage 只支持字符串类型的存储,
    //所以需要使用 JSON.stringify() 方法将数据对象value转换为字符串


  }
  /**
   * 获取数据
   * @param {string} key 
   * @returns  {Promise}
   */
  static get(key) {
    //读取存储在 AsyncStorage 中的数据时,会得到一个 JSON 字符串
    //需要使用 JSON.parse() 将其转换回 JavaScript 对象
    //使用then 在获取的key后面写一个function 我们这里用then来取到具体的数据 value
    //value后面是执行函数 来判断 和处理value为空的情况 
    return AsyncStorage.getItem(key).then(value => {
      if (value && value != '') {
        // 如果value 有数据且 不是空字符的情况下
        const jsonValue = JSON.parse(value)
        return jsonValue
      }

    }).catch(() => null)
    //  .then后面我们还可以写.catch 对异常进行操作


  }
  /**
   * 更新数据
   * @param {string} key 
   * @param {mixed} newValue 
   * @returns  {Promise}
   */
  static update(key, newValue) {
    return AsyncStorage.getItem(key).then(oldValue => {
      //通过 typeof 来判断 newValue 的类型 
      //三元表达式 是string 则不做任何处理 否则 判定为复杂结构的对象Object
      //这时候 我们调用一下Object 中的assign方法 可以合并对象当中的同名属性
      newValue = typeof newValue === 'string' ? newValue : Object.assign({}, oldValue, newValue)
      return AsyncStorage.setItem(key, JSON.stringify(newValue))

    })

  }
  /**
   * 删除指定的 key
   * @param {} key 
   * @returns 
   */
  static delete(key) {
    return AsyncStorage.removeItem(key)
  }
  /**
   * 清空所有数据
   * @returns 
   * 
   */
  static clear() {
    return AsyncStorage.clear()
  }
}

// 将 Storage  导出 
export  default Storage
  

自己封装模块的使用

index.js

import { Text, StyleSheet, View, Button } from 'react-native'
import React, { Component } from 'react'
import AsyncStorage from '@react-native-async-storage/async-storage'
import Storage from './storage'

export default class index extends Component {
  storeData = async (value) => {
    try {
      await AsyncStorage.setItem('mytest', value)
    } catch (e) {
      // 保存错误
    }
  }
  getData = async () => {
    try {
      const value = await AsyncStorage.getItem('mytest')
      //保持key都是 mytest 
      if (value !== null) {
        alert(value)
      } else {
        alert('value == null')
      }
    } catch (e) {
      // read error
    }



    console.log('Done.')
  }

  addData = async (value) => {
    try {
      // await AsyncStorage.setItem('mytest01', value)
      await Storage.set('mytest01', value)

    } catch (e) {
      // 保存错误
    }
  }

  getMyData = async () => {
    try {
      const value = await AsyncStorage.getItem('mytest01')
      //保持key都是 mytest 
      if (value !== null) {
        alert(value)
      } else {
        alert('value == null001')
      } 
    } catch (e) {
      // read error
    }



    console.log('Done.')
  }

  render() {
    return (
      <View styles={[styles.container]}>
        <Text></Text>
        <Text></Text>

        {/* /在storeData中传入参数  */}
        {/* 实现方式是在 onPress 属性中直接调用函数并传递参数,这会导致在组件渲染时立即调用这些函数,而不是等到按钮被点击时调用。
         */}
        <Button title='原生:存储' onPress={this.storeData('Hello wdm')} />
        <Button title='原生:获取' onPress={this.getData} />
        {/* // 直接掉用模块里面的清空方法 来测试是否导入模块成功 */}

        <Button title='清空' onPress={Storage.clear} />
        {/* onPress 事件处理器中使用 () => 来允许定义一个函数,而无需使用 function 关键字。
        这使得代码更加简洁易读。
        这里 () => 后面跟着的 {} 中是函数体,如果函数体只有一条语句,
        甚至可以省略 {} 和 return 语句: 
        () => {
  this.addData('Hello wdm001');
}

等同于 () => this.addData('Hello wdm001')
  */}
        {/* 应该将 onPress 的值设置为一个函数,当按钮被点击时调用这个函数。
        如果需要传递参数,可以使用箭头函数来封装调用。 */}
        <Button title='自制:存储' onPress={() => { this.addData('Hello 001') }} />
        <Button title='自制:获取' onPress={this.getMyData} />



      </View>
    )
  }
}

const styles = StyleSheet.create({

  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'

  }

})
4 geolocation获取定位

在这里插入图片描述

安装

npm install react-native-geolocation-service

或者

yarn add react-native-geolocation-service

适当配置了 Info.plist 文件来请求位置权限,添加描述依赖

<key>NSLocationWhenInUseUsageDescription</key>
<string>We need access to your location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>We need access to your location</string>

报错尝试重新装依赖:
yarn install

cd ios
pod install
cd ..

运行前清除缓存

yarn start --reset-cache

运用:

import React, { Component } from 'react';
import { View, Text, Button, StyleSheet, Platform } from 'react-native';
import Geolocation from 'react-native-geolocation-service';

// 定义 GeoLocationExample 组件,它继承了 Component 类
export default class GeoLocationExample extends Component {
  // 初始化组件状态
  state = {
    location: null, // 存储位置信息
    loading: false, // 标记是否正在获取位置
    error: null // 存储可能发生的错误信息
  };

  // 组件挂载后调用(组件被加载到屏幕上时)
  componentDidMount() {
    this.requestLocationPermission(); // 请求位置权限
  }

  // 请求位置权限的函数
  requestLocationPermission = () => {
    if (Platform.OS === 'ios') { // 检查操作系统是否是 iOS
      // 请求位置权限
      Geolocation.requestAuthorization('whenInUse').then(result => {
        if (result === 'granted') { // 如果用户授予位置权限
          this.getLocation(); // 获取位置信息
        } else {
          // 如果用户拒绝权限,更新错误状态
          this.setState({ error: 'Location permission not granted' });
        }
      });
    }
  };

  // 获取位置信息的函数
  getLocation = () => {
    this.setState({ loading: true, error: null }); // 开始加载,重置错误信息
    Geolocation.getCurrentPosition(
      (position) => {
        // 成功获取位置信息后的回调函数
        this.setState({ location: position, loading: false }); // 更新位置信息,停止加载
      },
      (error) => {
        // 获取位置失败后的回调函数
        this.setState({ loading: false, error: error.message }); // 停止加载,更新错误信息
      },
      // 高精度位置信息的选项
      { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
    );
  };

  // 渲染组件的函数
  render() {
    const { location, loading, error } = this.state; // 从 state 中解构所需的数据
    return (
      <View style={styles.container}>
        <Text>Location Info:</Text>
        {loading && <Text>Loading...</Text>} 
        {/* // 如果正在加载,显示加载提示 */}
        {error && <Text>Error: {error}</Text>} 
        {/* // 如果有错误,显示错误信息 */}
        {location && (
          <Text>
            {/* // 如果位置信息存在,显示经纬度 */}
            Latitude: {location.coords.latitude}, Longitude: {location.coords.longitude}
          </Text>
        )}
        <Button title="Get Location" onPress={this.getLocation} /> 
        {/* // 按钮用来触发获取位置的函数 */}
      </View>
    );
  }
}

// StyleSheet 创建组件的样式
const styles = StyleSheet.create({
  container: {
    flex: 1, // 组件占满整个屏幕
    justifyContent: 'center', // 子元素垂直居中
    alignItems: 'center', // 子元素水平居中
    padding: 20 // 内边距为 20
  }
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/565315.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言 分支控制语句之 if

然后 我们来说 流程控制语句之 if 选择控制结构 是通过 分支语句来实现的 其中 包括 单分支选择语句通过 (if) 来实现 双分支语句通过 (if) 和 (else) 实现 多分支语句通过 (if) (else if) (else) 实现 对于单分支来讲 它控制的语句就是 要嘛做 要嘛不做 好比如 放假了 你是…

MySQL基础之单表操作(定义DDL,增删改DML,查DQL)

目录 一、概述1.1 什么是数据库1.2 连接MySQL1.3 数据模型1.4 SQL语句的分类1.5 数据类型 二、数据库设计-DDL2.1 数据库层面2.2 数据表层面创建表约束查询修改add,modify,change,drop,rename删除 三、数据库操作-DML3.1 添加数据insert3.2 修改数据update3.3 删除数据delete 四…

插值与重采样在AI去衣技术中的关键作用

在人工智能&#xff08;AI&#xff09;的众多应用中&#xff0c;去衣技术作为一种新兴的图像处理技术&#xff0c;逐渐引起了广泛关注。这项技术不仅涉及复杂的计算机视觉和深度学习算法&#xff0c;还需要对图像处理中的插值与重采样技术有深入的理解。本文将详细探讨插值与重…

霸气归来,AKG N9 Hybrid头戴式降噪耳机震撼发布!手边的“大耳”瞬间不香了?

自1947年Rudolf Grike博士和Ernst Pless先生在“音乐之都”维也纳创立AKG以来&#xff0c;品牌已经走过77载辉煌历程&#xff0c;其产品被广泛应用于全球各大巡回演出和录音棚中&#xff0c;为全球音乐爱好者和专业人士提供了无数优质的声音体验。 近日&#xff0c;AKG再度以王…

(一)Java EE企业级应用开发实战之Servlet教程——JDK安装

首先打开清华大学开源软件镜像站&#xff0c;清华大学开源镜像网站地址为&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/ 打开该地址后的界面显示如下图所示 找到8版本对应的SDK安装包&#xff0c;我现在用的开发机器是Windows&#xff0c;所以我找的是Windows对应的版本…

手机文件怎么传给商家打印?

在数字化时代&#xff0c;手机已经成为我们生活和工作中不可或缺的工具。当需要将手机中的文件传给商家打印时&#xff0c;传统的打印店往往要求通过微信等社交软件传输文件&#xff0c;这种方式非常操作繁琐。那么&#xff0c;手机文件怎么传给商家打印呢&#xff1f;琢贝云打…

Kotlin语法快速入门-函数(4)

Kotlin语法快速入门-函数&#xff08;4&#xff09; 文章目录 Kotlin语法快速入门-函数&#xff08;4&#xff09;四、函数1、函数定义2、infix关键字3、参数省略4、函数类型参数5、多参数--vararg 四、函数 1、函数定义 fun 函数名(参数: 类型) &#xff1a;返回值类型{//函…

“EDM邮件营销”如何构建企业获客增长新赛道

在这个瞬息万变的数字时代&#xff0c;企业的营销策略不断进化&#xff0c;以求在激烈的市场竞争中脱颖而出。其中&#xff0c;“EDM&#xff08;Electronic Direct Mail&#xff09;邮件营销”作为一项经典且高效的营销手段&#xff0c;正借助先进的技术力量&#xff0c;重新焕…

网络常识!!!

网络常识!!! 一:网络的发展史二:关键的概念三:IP地址四:端口号二级目录二级目录二级目录二级目录三级目录 一:网络的发展史 从游戏方面发展历程进行理解: 从单机游戏-----游戏支持局域网对战-------游戏支持广域网对战-------移动端 (1)局域网对战:在同一个网吧里,不同的游戏…

stable diffusion本地部署@win10

一键无脑安装stable-diffusion-webui stable diffusion是当前非常出色的文生图模型&#xff0c;要优于以前gan文生图模型。现在有了stable-diffusion-webui软件&#xff0c;可以一键安装&#xff0c;大大简化了操作难度。本文档就是stable-diffusion-webui在windows 10上的安装…

MySql 安装教程+简单的建表

目录 1.安装准备 1.MySQL官方网站下载 2.安装步骤 3.测试安装 4.简单的建表 1.安装准备 1.MySQL官方网站下载 下载安装包或者压缩包都可以 选择相应版本&#xff0c;点击Download开始通过网页下载到本地&#xff08;压缩包下载快一些&#xff09; 2.安装步骤 双击此.exe…

SpringAOP从入门到源码分析大全(三)ProxyFactory源码分析

文章目录 系列文档索引五、ProxyFactory源码分析1、案例2、认识TargetSource&#xff08;1&#xff09;何时用到TargetSource&#xff08;2&#xff09;Lazy的原理&#xff08;3&#xff09;应用TargetSource 3、ProxyFactory选择cglib或jdk动态代理原理4、jdk代理获取代理方法…

Java学习笔记29(泛型)

1.泛型 ArrayList<Dog> arrayList new ArrayList<Dog>(); //1.当我们ArrayList<Dog>表示存放到ArrayList集合中的元素是Dog类 //2.如果编译器发现添加的类型&#xff0c;不满足要求&#xff0c;就会报错 //3.在便利的时候&#xff0c;可以直接取出Dog类型而…

go的编译以及运行时环境

开篇 很多语言都有自己的运行时环境&#xff0c;go自然也不例外&#xff0c;那么今天我们就来讲讲go语言的运行时环境&#xff01; 不同语言的运行时环境对比 我们都知道Java的运行时环境是jvm &#xff0c;javascript的运行时环境是浏览器内核 Java -->jvm javascript…

进阶C语言-文件操作

文件操作 &#x1f388;1.为什么使用文件&#x1f388;2.什么是文件&#x1f52d;2.1程序文件&#x1f52d;2.2数据文件&#x1f52d;2.3文件名 &#x1f388;3.文件的打开和关闭&#x1f52d;3.1文件指针&#x1f52d;3.2文件的打开和关闭 &#x1f388;1.为什么使用文件 ✅ 我…

【从浅学到熟知Linux】进程间通信之匿名管道方式(进程间通信方式汇总、匿名管道的创建、匿名管道实现进程池详解)

&#x1f3e0;关于专栏&#xff1a;Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程等内容。 &#x1f3af;每天努力一点点&#xff0c;技术变化看得见 文章目录 进程间通信介绍如何实现进程间通信进程间通信分类 管道通信方式什么是管道匿名管道pipe匿名管道读写规则管…

ros Moveit学习记录(一) MoveIt Setup Assistant

ros MoveIt Setup Assistant 记录 1. 准备工作2. 使用记录a. 打开Moveit! Setup Assistantb. *Create New Moveit Configuration* -> 填入urdf.xacro的地址c. Self-Collisions&#xff1a;全选了即可d. Define Virtual Jointse. Define Planning Groupsf. Define Robot Pose…

腾讯云服务器价格明细表2024年最新(CPU内存/带宽/磁盘)

腾讯云服务器价格明细表2024年最新&#xff08;CPU内存/带宽/磁盘&#xff09;腾讯云服务器租用优惠价格表&#xff1a;轻量应用服务器2核2G3M价格61元一年&#xff0c;2核2G4M价格99元一年、135元15个月、540元三年&#xff0c;2核4G5M带宽165元一年、252元15个月、756元3年&a…

@NameBinding注解名称绑定过滤器/拦截器

NameBinding注解名称绑定过滤器/拦截器&#xff0c;只针对某一些资源方法执行处理逻辑 一、为什么要用名称绑定 一般情况下&#xff0c;借助Spring的过滤器或者拦截器等对Http请求或响应进行处理就能满足需求。但是在有些场景下若只需对特定的xxxResource做拦截处理&#xff0…

vivado 自定义波形配置

自定义配置 您可使用下表中列示并简述的功能来自定义波形配置 &#xff1b; 其中功能名称链接至提供功能完整描述的相应小节。 光标 光标主要用作为样本位置的临时指示符并且会频繁移动 &#xff0c; 比如测量 2 个波形边沿之间的距离 &#xff08; 以样本数为单位 &#x…