React Native에서 투명한 배경색을 설정하는 방법


139

이것은 내가 사용한보기의 스타일입니다.

backCover: {
  position: 'absolute',
  marginTop: 20,
  top: 0,
  bottom: 0,
  left: 0,
  right: 0,
}

현재 흰색 배경이 있습니다. 원하는대로 backgroundColor를 변경할 수 '#343434'있지만 색상에 대해 최대 6 개의 16 진수 값만 허용하므로 불투명도를 줄 수는 없습니다 '#00ffffff'. 나는 이와 같은 불투명도를 사용해 보았습니다.

backCover: {
  position: 'absolute',
  marginTop: 20,
  top: 0,
  bottom: 0,
  left: 0,
  right: 0,
  opacity: 0.5,
}

그러나 뷰 컨텐츠의 가시성을 줄입니다. 그래서 어떤 대답?

답변:


288

rgba값을 사용하십시오 backgroundColor.

예를 들어

backgroundColor: 'rgba(52, 52, 52, 0.8)'

불투명도 10 %에서 파생 된 불투명도가 80 % 인 회색으로 설정됩니다 0.8. 이 값은 0.0~ 사이의 값이 될 수 있습니다 1.0.


왜 지구상에서 컬러 발이 8 비트이고 알파 발이 뜨는가?
duhaime

@duhaime, 왜 구체적으로 확실하지 않지만 8 비트는 메모리 의미 (특히 역사적으로)에서 의미가 있습니다. 알파 값은 완전히 투명하거나 완전히 불투명하기 위해 0과 1을 최소 및 최대로 설정하는 것이 좋습니다. 예를 들어, 무언가를 25 % 투명하게하려면 255의 1/4이 무엇인지 파악하고 싶지 않습니다.
kojow7

104

다음은 잘 작동합니다.

backgroundColor: 'rgba(52, 52, 52, alpha)'

시도해 볼 수도 있습니다.

backgroundColor: 'transparent'

2
backgroundColor : '투명'은 가장 쉬운 솔루션입니다.
NathanL

27

backgroundColor: '#00000000' 배경색을 투명하게 설정 하십시오. #rrggbbaa 16 진수 코드를 따릅니다.


어떤 이유로이 변형은 결과 색상이 불투명하게 잘못 표시됩니다. 내가 실수하지 않으면 RN의 버그입니다. 따라서 rgba방법 을 사용하는 것이 좋습니다 .
Shyngys Kassymov


@O 흥미 롭군요. 지적 해 주셔서 감사합니다! 그러나 IMO는 rgba방법 을 사용하는 것이 더 쉽습니다 :)
Shyngys Kassymov

형식이 #aarrggbb 여야한다는 것을 의미합니까?
Shyngys Kassymov

에서 hexavalue를 사용할 수 있음을 의미했습니다 rrggbbaa.

3

iOS 및 RGBA 배경에서 발생하는 현재 충돌에 대해 알고 있어야합니다.

요약 : public React Native는 현재 iOS 레이어 섀도우 속성을 거의 직접적으로 노출하지만 이에 대한 많은 문제가 있습니다.

1) 이러한 속성을 사용할 때의 성능은 기본적으로 좋지 않습니다. iOS는 투명한 콘텐츠와 모든 하위 뷰를 포함하여 뷰의 정확한 픽셀 마스크를 가져 와서 그림자를 계산하기 때문에 CPU와 GPU를 많이 사용하기 때문입니다. 2) iOS 그림자 속성은 CSS 상자 그림자 표준의 구문 또는 의미와 일치하지 않으며 Android에서 구현할 수 없습니다. 3) layer.shadowPath레이어 그림자에서 좋은 성능을 얻는 데 중요한 속성을 노출하지 않습니다 .

이 diff는 shadowPath불투명 한 배경을 가진 뷰의 뷰 경계와 일치 하는 기본값 을 구현하여 문제 번호 1)을 해결 합니다. 이는 일반적인 사용 사례를 최적화하여 그림자의 성능을 향상시킵니다. 또한 그림자 소품이있는 뷰의 배경색 전파를 복원했습니다. 이렇게하면 최상의 시나리오가 더 자주 발생하도록해야합니다.

명시 적으로 투명한 배경이있는 뷰의 경우 그림자는 이전과 같이 계속 작동합니다 ( shadowPath설정되지 않은 상태로 유지되고 그림자는 뷰의 픽셀과 하위 뷰에서 정확하게 파생 됨). 이것이 성능에 대한 최악의 경로이므로 절대적으로 필요한 경우가 아니면 피해야합니다. 이 기능에 대한 지원은 나중에 기본적으로 비활성화되어 있거나 완전히 삭제 될 수 있습니다.

반투명 이미지의 경우 그림자를 이미지 자체에 굽거나 다른 메커니즘을 사용하여 그림자를 미리 생성하는 것이 좋습니다. 텍스트 그림자의 경우 크로스 플랫폼에서 작동하고 성능이 훨씬 뛰어난 textShadow 속성을 사용해야합니다.

문제 번호 2)는 iOS shadowXXX 속성의 이름을 boxShadowXXX로 바꾸고 CSS 표준에 맞게 구문과 의미를 변경하여 향후 차이점에서 해결 될 것입니다.

우리가 shadowPath를 자동으로 생성하기 때문에 문제 번호 3)이 이제는 대부분 문제가 있습니다. 향후 그림자를보다 정밀하게 제어해야하는 경우 경로를 명시 적으로 설정하기 위해 iOS 전용 소품을 제공 할 수 있습니다.

검토 자 : weicool

커밋 : https://github.com/facebook/react-native/commit/e4c53c28aea7e067e48f5c8c0100c7cafc031b06


2

놀랍게도 아무도 이것에 대해 말하지 않았습니다.

style={{
backgroundColor: 'white',
opacity: 0.7
}}

6
이 솔루션은 배경뿐만 아니라 전체보기에 대한 불투명도를 정의하여 모든 하위 요소도 반투명하게됩니다 (원래 질문에서 지적 됨)
Cool Soft

-1

다음은 모든 화면에서 렌더링되고 App.tsx에서 초기화 될 수있는 모달에 대한 솔루션입니다.

ModalComponent.tsx

import React, { Component } from 'react';
import { Modal, Text, TouchableHighlight, View, StyleSheet, Platform } from 'react-native';
import EventEmitter from 'events';
// I keep localization files for strings and device metrics like height and width which are used for styling 
import strings from '../../config/strings';
import metrics from '../../config/metrics';

const emitter = new EventEmitter();
export const _modalEmitter = emitter

export class ModalView extends Component {
    state: {
        modalVisible: boolean,
        text: string, 
        callbackSubmit: any, 
        callbackCancel: any,
        animation: any
    }

    constructor(props) {
        super(props)
        this.state = {
            modalVisible: false,
            text: "", 
            callbackSubmit: (() => {}), 
            callbackCancel: (() => {}),
            animation: new Animated.Value(0)
        } 
    }

    componentDidMount() {
        _modalEmitter.addListener(strings.modalOpen, (event) => {
            var state = {
                modalVisible: true,
                text: event.text, 
                callbackSubmit: event.onSubmit, 
                callbackCancel: event.onClose,
                animation: new Animated.Value(0)
            } 
            this.setState(state)
        })
        _modalEmitter.addListener(strings.modalClose, (event) => {
            var state = {
                modalVisible: false,
                text: "", 
                callbackSubmit: (() => {}), 
                callbackCancel: (() => {}),
                animation: new Animated.Value(0)
            } 
            this.setState(state)
        })
    }

    componentWillUnmount() {
        var state = {
            modalVisible: false,
            text: "", 
            callbackSubmit: (() => {}), 
            callbackCancel: (() => {})
        } 
        this.setState(state)
    }

    closeModal = () => {
        _modalEmitter.emit(strings.modalClose)
    }

    startAnimation=()=>{
        Animated.timing(this.state.animation, {
            toValue : 0.5,
            duration : 500
        }).start()
    }

    body = () => {
        const animatedOpacity ={
            opacity : this.state.animation
        }
        this.startAnimation()
        return (
            <View style={{ height: 0 }}>
                <Modal
                    animationType="fade"
                    transparent={true}
                    visible={this.state.modalVisible}>

                    // render a transparent gray background over the whole screen and animate it to fade in, touchable opacity to close modal on click out

                    <Animated.View style={[styles.modalBackground, animatedOpacity]} > 
                        <TouchableOpacity onPress={() => this.closeModal()} activeOpacity={1} style={[styles.modalBackground, {opacity: 1} ]} > 
                        </TouchableOpacity>
                    </Animated.View>

                    // render an absolutely positioned modal component over that background
                    <View style={styles.modalContent}>

                        <View key="text_container">
                            <Text>{this.state.text}?</Text>
                        </View>
                        <View key="options_container">
                            // keep in mind the content styling is very minimal for this example, you can put in your own component here or style and make it behave as you wish
                            <TouchableOpacity
                                onPress={() => {
                                    this.state.callbackSubmit();
                                }}>
                                <Text>Confirm</Text>
                            </TouchableOpacity>

                            <TouchableOpacity
                                onPress={() => {
                                    this.state.callbackCancel();
                                }}>
                                <Text>Cancel</Text>
                            </TouchableOpacity>

                        </View>
                    </View>
                </Modal>
            </View> 
        );
    }

    render() {
        return this.body()
    }
}

// to center the modal on your screen 
// top: metrics.DEVICE_HEIGHT/2 positions the top of the modal at the center of your screen
// however you wanna consider your modal's height and subtract half of that so that the 
// center of the modal is centered not the top, additionally for 'ios' taking into consideration
// the 20px top bunny ears offset hence - (Platform.OS == 'ios'? 120 : 100)
// where 100 is half of the modal's height of 200
const styles = StyleSheet.create({
    modalBackground: {
        height: '100%', 
        width: '100%', 
        backgroundColor: 'gray', 
        zIndex: -1 
    },
    modalContent: { 
        position: 'absolute', 
        alignSelf: 'center', 
        zIndex: 1, 
        top: metrics.DEVICE_HEIGHT/2 - (Platform.OS == 'ios'? 120 : 100), 
        justifyContent: 'center', 
        alignItems: 'center', 
        display: 'flex', 
        height: 200, 
        width: '80%', 
        borderRadius: 27,
        backgroundColor: 'white', 
        opacity: 1 
    },
})

App.tsx 렌더링 및 가져 오기

import { ModalView } from './{your_path}/ModalComponent';

render() {
    return (
        <React.Fragment>
            <StatusBar barStyle={'dark-content'} />
            <AppRouter />
            <ModalView />
        </React.Fragment>
    )
}

모든 구성 요소에서 사용

SomeComponent.tsx

import { _modalEmitter } from './{your_path}/ModalComponent'

// Some functions within your component

showModal(modalText, callbackOnSubmit, callbackOnClose) {
    _modalEmitter.emit(strings.modalOpen, { text: modalText, onSubmit: callbackOnSubmit.bind(this), onClose: callbackOnClose.bind(this) })
}

closeModal() {
    _modalEmitter.emit(strings.modalClose)
}

내가 당신 중 일부를 도울 수 있기를 바랍니다. 나는 인앱 알림에 매우 유사한 구조를 사용했습니다.

행복한 코딩

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.