Cách ngăn bố cục chồng chéo với thanh trạng thái iOS


81

Tôi đang làm việc về hướng dẫn điều hướng React Native. Tôi phát hiện ra rằng tất cả bố cục bắt đầu tải từ đầu màn hình thay vì bên dưới thanh trạng thái. Điều này khiến hầu hết các bố cục trùng lặp với thanh trạng thái. Tôi có thể khắc phục điều này bằng cách thêm phần đệm vào chế độ xem khi tải chúng. Đây có phải là cách thực tế để làm điều đó? Tôi không nghĩ rằng việc thêm đệm theo cách thủ công là một cách thực tế để giải quyết nó. Có cách nào thanh lịch hơn để sửa lỗi này không?

import React, { Component } from 'react';
import { View, Text, Navigator } from 'react-native';

export default class MyScene extends Component {
    static get defaultProps() {
            return {
                    title : 'MyScene'    
            };  
    }   
    render() {
            return (
                    <View style={{padding: 20}}> //padding to prevent overlap
                            <Text>Hi! My name is {this.props.title}.</Text>
                    </View> 
            )   
    }    
}

Dưới đây hiển thị ảnh chụp màn hình trước và sau khi thêm phần đệm. nhập mô tả hình ảnh ở đây


13
Câu hỏi hay, nhưng có lẽ bạn có thể cắt bớt hình ảnh.
Quv

stackoverflow.com/a/39300715/1540350 <- câu trả lời này sẽ không chỉ khắc phục sự cố được đề cập ở đây mà thậm chí còn cung cấp cho bạn khả năng tô màu nền của thanh trạng thái trong iOS và Android.
Martin Braun

Câu trả lời:


36

Có một cách rất đơn giản để sửa lỗi này. Tạo một thành phần.

Bạn có thể tạo một thành phần StatusBar và gọi nó đầu tiên sau trình bao bọc chế độ xem đầu tiên trong các thành phần mẹ của bạn.

Đây là mã cho cái tôi sử dụng:

'use strict'
import React, {Component} from 'react';
import {View, Text, StyleSheet, Platform} from 'react-native';

class StatusBarBackground extends Component{
  render(){
    return(
      <View style={[styles.statusBarBackground, this.props.style || {}]}> //This part is just so you can change the color of the status bar from the parents by passing it as a prop
      </View>
    );
  }
}

const styles = StyleSheet.create({
  statusBarBackground: {
    height: (Platform.OS === 'ios') ? 18 : 0, //this is just to test if the platform is iOS to give it a height of 18, else, no height (Android apps have their own status bar)
    backgroundColor: "white",
  }

})

module.exports= StatusBarBackground

Sau khi thực hiện việc này và xuất nó sang thành phần chính của bạn, hãy gọi nó như sau:

import StatusBarBackground from './YourPath/StatusBarBackground'

export default class MyScene extends Component {
  render(){
    return(
      <View>
        <StatusBarBackground style={{backgroundColor:'midnightblue'}}/>
      </View>
    )
  }
}

 


MidnightBluekhông hợp lệ, được thông báo bởi React Native: Cảnh báo: Loại đề xuất không thành công: Đã backgroundColorcung cấp đề xuất không hợp lệ
Raptor

2
Nó nên được midnightblue.
bblincoe

19
Thanh trạng thái iOS không phải là kích thước cố định. Nó có thể lớn hơn khi chia sẻ Wifi hoặc trong một cuộc gọi.
edA-qa mort-ora-y

1
Làm thế nào để sử dụng này khi sử dụng Phản ứng chuyển hướng hookup với Redux, tất cả các trang hoặc là trong một ngăn xếp hoa tiêu hoặc tab navigator (lồng) và móc với Redux
Yasir

5
Nếu bạn nhập thành phần gốc phản ứng "StatusBar" và sau đó sử dụng: height: (Platform.OS === 'ios') ? 20 : StatusBar.currentHeight,thay vì ? 20 : 0,bạn sẽ nhận được kết quả tương tự trên Android.
mrroot

60

Bây giờ bạn có thể sử dụng SafeAreaViewcái được bao gồm trong React Navigation:

<SafeAreaView>
    ... your content ...
</SafeAreaView>

2
Có thể tốt khi lưu ý rằng thành phần này được bao gồm trong react-navigationmặc định ngay bây giờ.
Aᴄʜᴇʀᴏɴғᴀɪʟ

13
điều này không giải quyết được vấn đề chồng chéo thanh trạng thái - Tôi đã bọc ứng dụng của mình trong SafeAreaView và ứng dụng của tôi vẫn chồng lên StatusBar. Có vẻ như nó đang hướng đến tình trạng iPhone X có notch / góc tròn
izikandrw

Bạn không bọc ứng dụng của mình trong đó, bạn bọc một màn hình trong đó.
Greg Ennis

Ồ, thật tuyệt! Tôi thích cái đó.
Asaf Katz

1
@AndreFigueosystemo Không đúng. Hoạt động tốt trên tất cả các thiết bị iPhone, miễn là nó> iOS 11.
Fellow Stranger

17

Tôi đã thử một cách đơn giản hơn cho việc này.

Chúng ta có thể lấy chiều cao của Status Bar trên Android và sử dụng SafeAreaView cùng với nó để làm cho mã hoạt động trên cả hai nền tảng.

import { SafeAreaView, StatusBar, Platform } from 'react-native';

Nếu chúng tôi đăng xuất Platform.OSStatusBar.currentHeightnhận được nhật ký,

console.log('Height on: ', Platform.OS, StatusBar.currentHeight);

Chiều cao trên: android 24 và Chiều cao trên: android 24

Bây giờ chúng tôi có thể tùy chọn thêm margin / padding vào chế độ xem vùng chứa của mình bằng cách sử dụng

paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0

Mã cuối cùng trong App.js là bên dưới:

export default class App extends React.Component {
  render() {
    return (
      <SafeAreaView style={{ flex: 1, backgroundColor: "#fff" }}>
        <View style={styles.container}>
          <Text>Hello World</Text>
        </View>
      </SafeAreaView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0
  }
});

1
Tôi đã thử nó trên Android và nó đang hoạt động. Tôi chưa thể thử nghiệm nó trên iOS, nhưng vì tôi biết SafeArea là gì trên iOS, tôi khá chắc chắn rằng nó cũng sẽ hoạt động ở đó.
manuelwaldner

*** Điều này phải được đặt thành câu trả lời được chấp nhận *** Các giải pháp khác ở đây cung cấp độ cao cố định tùy ý dựa trên tình huống thử nghiệm duy nhất của riêng chúng
mcmonkeys1

Một câu trả lời hoàn hảo nhưng SafeAreaView không áp dụng cho các thiết bị iPhone có phiên bản dưới 11
Pradeep

Làm việc tốt. Cảm ơn!
bruxo00

16

@philipheinser giải pháp thực sự hoạt động.

Tuy nhiên, tôi mong đợi rằng StatusBar của React Native thành phần sẽ xử lý điều đó cho chúng tôi.

Thật không may, nó không, nhưng chúng ta có thể trừu tượng hóa điều đó khá dễ dàng bằng cách tạo thành phần của riêng chúng ta xung quanh nó:

./StatusBar.js

import React from 'react';
import { View, StatusBar, Platform } from 'react-native';

// here, we add the spacing for iOS
// and pass the rest of the props to React Native's StatusBar

export default function (props) {
    const height = (Platform.OS === 'ios') ? 20 : 0;
    const { backgroundColor } = props;

    return (
        <View style={{ height, backgroundColor }}>
            <StatusBar { ...props } />
        </View>
    );
}

./index.js

import React from 'react';
import { View } from 'react-native';

import StatusBar from './StatusBar';

export default function App () {
    return (
      <View>
        <StatusBar backgroundColor="#2EBD6B" barStyle="light-content" />
        { /* rest of our app */ }
      </View>
    )
}
Trước:

Sau:


4

Các react-navigationtài liệu có một giải pháp tuyệt vời cho điều này. Trước hết, họ khuyên bạn không nên sử dụng phần mềm đi SafeAreaViewkèm với React Native vì:

Trong khi React Native xuất thành phần SafeAreaView, nó có một số vấn đề cố hữu, tức là nếu màn hình chứa vùng an toàn đang hoạt động, nó gây ra hành vi nhảy vọt. Ngoài ra, thành phần này chỉ hỗ trợ iOS 10+ mà không hỗ trợ các phiên bản iOS cũ hơn hoặc Android. Chúng tôi khuyên bạn nên sử dụng thư viện bối cảnh vùng phản ứng-gốc-an toàn để xử lý các khu vực an toàn theo cách đáng tin cậy hơn.

Thay vào đó, họ đề xuất phản ứng-gốc-vùng-an-toàn-bối cảnh - mà nó sẽ trông như thế này:

import React, { Component } from 'react';
import { View, Text, Navigator } from 'react-native';
import { useSafeArea } from 'react-native-safe-area-context';

export default function MyScene({title = 'MyScene'}) {
    const insets = useSafeArea();

    return (
        <View style={{paddingTop: insets.top}}>
            <Text>Hi! My name is {title}.</Text>
        </View> 
    )   
}

Tôi muốn lưu ý rằng có lẽ tốt hơn nên sử dụng SafeAreaViewthư viện này cung cấp, vì điện thoại ngày nay cũng có thể có các phần tử ở dưới cùng có thể chồng lên các phần tử giao diện người dùng. Tất nhiên, tất cả phụ thuộc vào ứng dụng của bạn. (Để biết thêm chi tiết về điều đó, hãy xem các react-navigationtài liệu tôi đã liên kết lúc đầu.)


2

Đây là một cách hoạt động cho iOS :

<View style={{height: 20, backgroundColor: 'white', marginTop: -20, zIndex: 2}}>
   <StatusBar barStyle="dark-content"/></View>

1

Bạn có thể xử lý điều này bằng cách thêm phần đệm vào thành phần thanh điều hướng hoặc chỉ quảng cáo một chế độ xem có cùng độ cao với thanh trạng thái ở đầu cây chế độ xem của bạn với màu nền giống như ứng dụng facebook thực hiện điều này.


6
Giá trị độ cao đó có cố định và không thay đổi cho dù bạn có điện thoại nào không? Nếu vậy, tôi có thể tìm thông tin về giá trị cụ thể chính xác cho iOS / Android ở đâu?
nbkhope

0

Chỉ cần người dùng phản ứng đơn giản Thanh trạng thái mặc định riêng để đạt được sự thú vị này.

<View style={styles.container}>
    <StatusBar backgroundColor={Color.TRANSPARENT} translucent={true} />
    <MapView
      provider={PROVIDER_GOOGLE} // remove if not using Google Maps
      style={styles.map}
      region={{
        latitude: 37.78825,
        longitude: -122.4324,
        latitudeDelta: 0.015,
        longitudeDelta: 0.0121,
      }}
    />
  </View>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.