[React Native] Positioning

Nadan
Nadan Dev Blog

Positioning

-> 예제 변경할 것

참고 자료

● 부모(Parent)에서 사용하는 속성

flexDirection

  • column : child를 세로로 배치
  • row : child를 가로로 배치

alignItem

  • flexDirection이 column인 경우

    • stretch : 늘어날 수 있는만큼 가로로 늘어남
    • flex-start : box-model 만큼 남고 줄어들고, 왼쪽으로 붙음
    • flex-end : box-model 만큼 남고 줄어들고, 오른쪽으로 붙음
    • center : box-model 만큼 남고 줄어들고, 가운데 정렬
  • flexDirection이 row인 경우

    • default : 가로를 형제들이 똑같이 나누어 가짐(예를 들어 버튼 3개면 3등분)
    • stretch : 늘어날 수 있는만큼 세로로 늘어남
    • flext-start : box-model 만큼 남고 줄어들고, 위쪽으로 붙음
    • flex-end : box-model 만큼 남고 줄어들고, 아래로 붙음
    • center : box-model 만큼 남고 줄어들고, 가운데 정렬

justifyContent

  • flex-start
  • flex-end
  • center
  • space-between
  • space-around

● 자식(child), 일반 View가 스스로 정렬하는 속성

  • flex
  • alignSelf
  • position
  • top, left, right, bottom
  • fill
  • 속성은 아니고 absolute + top/left/right/bottom 0 으로 전체 채울 수 있음

● 상황별 뷰 배치

  • 전체화면

    • flex : 1
  • 남은 공간 채우기

    • alignSelf:stretch
    • flex : 1
  • 베젤까지 나가지 않도록 화면 크기 설정하기

    안드로이드는 아예 스크롤이 안 되고, iOS도 일부만 스크롤이 되는 문제가 있음. 리액트가 화면에 꽉 채워서, 일부는 bottom 네비게이션 밑까지 채우기 때문

    position 1

    해결1) flex: 1

    const SearchScreen = () => {
    
      ...
    
      return (
          <View style={{ flex: 1}}>
              <SearchBar 
                  term={term} 
                  onTermChange={setTerm}
                  onTermSubmit={() => searchAPI(term)}  />
              {errMsg ? <Text>{errMsg}</Text> : null}
              <Text>We have found {results.length} results</Text>
              <ScrollView>
                  <ResultsList results={filterResultsByPrice('$')} title="Cost Effective"/>
                  <ResultsList results={filterResultsByPrice('$$')} title="Bit Pricier"/>
                  <ResultsList results={filterResultsByPrice('$$$')} title="Big Spender"/>
              </ScrollView>
          </View>
      )
    }

    해결2) <></>로 씌워주기

    const SearchScreen = () => {
    
      ...
    
      return (
          <>
              <SearchBar 
                  term={term} 
                  onTermChange={setTerm}
                  onTermSubmit={() => searchAPI(term)}  />
              {errMsg ? <Text>{errMsg}</Text> : null}
              <Text>We have found {results.length} results</Text>
              <ScrollView>
                  <ResultsList results={filterResultsByPrice('$')} title="Cost Effective"/>
                  <ResultsList results={filterResultsByPrice('$$')} title="Bit Pricier"/>
                  <ResultsList results={filterResultsByPrice('$$$')} title="Big Spender"/>
              </ScrollView>
          </>
      )
    }
  • status bar 아래로 내려가게 하는 방법

    ...
    import { SafeAreaView } from 'react-navigation';
    
    const AccountScreen = () => {
    
      const { signout } = useContext(AuthContext);
    
      return (
          <SafeAreaView forceInset={{ top: 'always'}}>
              <Spacer>
                  <Text style={{ fontSize:48}}>Account Screen</Text>
                  <Button title="Sign Out" onPress={() => signout()} />
              </Spacer>
          </SafeAreaView>
      )
    }
    
    const styles = StyleSheet.create({});
    
    export default AccountScreen;
  • 리스트가 늘어나다보면 맨 밑의 아이템이 보이지 않는 경우

    • 컨테이너에 flex: 1 해주면 됨
  • 중앙 정렬

    • justifyContent

● 유의점

  • 부모가 화면을 꽉 채우지 않으면 자식에게 flex:1해도 화면을 채우지 않음

    const styles = StyleSheet.create({
      container: {
          flex: 1
      },
      list: {
          // backgroundColor: 'yellow'
      },
      itemContainer: {
          borderTopWidth: 1,
          borderColor: 'black',
          padding: 10
      },
      item: {
          fontSize: 20,
      }
    });