요번 포스팅에서는 크게 플렛폼 별 스타일링과 flexbox에 대해서 알아봅니다. 

 

일단 안드로이드와 iOS의 화면 단위(포인트, DP)자체가 달라 CSS코드에 스타일 속성 적용 시 특정 단위를 넣지 않습니다.(px,dp)

 

그 이유는 아래와 같으나  React native에서 알아서 조절해 주고 있으니 굳이 이해할 필요는 없습니다. 

(맥북을 사려는 여자친구에게 레티나 디스플레이로 아는 척 오지게 할 때 유용합니다.)

 

픽셀

- 가장 작은 프로그래밍 화면 단위

- 해상도는 가로 X 세로 픽셀 수를 말함

- PPI : 인치당 픽셀 수(초기 아이폰 163PPI)

-> 같은 해상도의 다른 화면 크기라면 이미지의 선명도가 다르게 나옴

 

애플의 레티나 디스플레이는 기존 화면의 4배의 해상도를 가지므로 이론적으론 기존 이미지의 크기가 레티나에서는 4분의1 크기로 보이게 됩니다.(이미지의 크기는 이미 특정 픽셀로 고정이 되어 있으므로) 애플은 여기서 point라는 논리적인 개념을 도입해서 일반 디스플레이와 레티나 디스플레이에서 이미지를 봤을때 차이가 없도록 합니다.

* 반면 안드로이드는 DP라는 디바이스 독립적인 논리 개념을 도입(160PPI)하고 있습니다. 

 

결국 디스플레이 스펙 별, 플렛폼 별 눈에 보이는 요소의 크기를 일관성 있게 유지 해주기 위해 X2, X3의 논리적인 배수를 적용한다는 의미? 입니다. 

 

앞서 텍스트에 그림자 속성을 넣었듯이 View에 그림자 속성을 넣어 보겠습니다. 그림자가 대표적인 플렛폼 별 설정을 달리해야 하는 속성입니다.

iOS : shadowPropTypesIOS (shadowOffset, shadowOpacity, shadowRadius 같이 세부 속성으로 설정)

Android : elevation (겹쳐진 레이어의 우선 순위를 설정 그림자 레이어를 뒤에 실물 레이어를 앞에 두는 방식)

 

- Platform을 import

- ...Platform.select({ ios: {...}, android:{...} }) 를 통해 플렛폼 별 스타일 적용 코드를 추가

* 디버거를 붙인 상태에서 platform 유틸리티를 쓰려고 했더니 제대로 작동하지 않는 것 같았습니다. 잠시 디버거(크롬 개발자도구)를 끕니다. (백그라운드 디버거로 인한 작동 성능이 저조 할 수 있다는 경고 메세지가 emulator에 뜹니다.)

 

 

 

 

 

 

 

 

 

프로필 이미지, 카드 전체 아래에 그림자 효과가 적용된 것을 볼 수 있습니다. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반면 안드로이드에서는... 희미하게 적용된 그림자를 볼 수 있습니다.

 

 

 

 

 

 

 

 

 

Component 변형

component의 좌표 변경등을 통해 애니메이션 효과를 주기위한 속성들로 transform으로 시작하여 속성을 적용 가능합니다.

(e.g. transform: [{rotate: '90deg', scale: .5}])

*아래 다양한 변형 속성들을 배열 형태로 여러개 사용할 수 있으나 그 적용 순서에 따라 전혀 다른 결과가 만들어 질 수 있습니다.

- perspective : z-index를 조절하는 방식으로 3D 효과를 줄 수 있음

- translateX,Y : 요소의 평면 이동 아래, 우측이 + 수치임

- rotateX, Y, Z : 요소의 축회전 X(위아래), Y(좌우), Z(회전)

- backfaceVisibility : 요소가 회전했을때 반대면을 보여줄 것인가?에 대한 속성

- scale, X,Y : 요소의 크기를 조절, 기본 수치는 1

- skewX, Y: 요소를 변형하면서 기울임.. 직접 해보심이.. (안드로이드에서는 정상동작하지 않는다 함)

 

*ㅎㅎ.. 요소를 직접 다루는 대신 Yoga라는 layout engine을 쓴다고 합니다.

 

flexbox (View에 적용되는 기본적인 스타일 속성)

* 아래 공식 사이트에서 flexbox 속성의 예제 코드와 결과 이미지를 확인 할 수 있습니다. 

https://facebook.github.io/react-native/docs/flexbox#__docusaurus

 

- flex : 안드로이드의 weight와 비슷한 속성으로 부모 요소 대비 얼마의 비율로 요소의 크기(다른 요소 대비)를 확보할 것인가 결정

- flexDirection : 'row'를 주면 요소들의 배치 방향을 가로로 전환한다. (기본 main axis는 세로(column) 방향)

- justifyContext : 여러 자식 요소들의 자신의 크기대로 적절한 위치로 배치 하는 방식(center, flex-start,end, space-around, space-between)

- alignItems : 부모 요소의 보조 축을 따라 자식 요소들을 어떻게 정렬할 것인지 결정(center, flex-start, end)

- alignSelf : 자식 요소 자신의 독립적인 alignItems 속성을 지정

- flexWrap : 'nowrap' 화면을 넘어가면 잘림, 'wrap' 잘리지 않고 다음줄에 표현, 적용 예는 아래 링크를 통해 확인해보자

(https://yogalayout.com/docs/flex-wrap/)

 

변형실습 (npm install immutability-helper --save 를 통해 component state update를 위한 helper 설치)

github/highstyle 참고

'React native' 카테고리의 다른 글

Animation  (0) 2020.01.05
Navigation  (0) 2020.01.02
Style  (0) 2019.12.27
Todo 2  (0) 2019.12.25
Todo 1  (0) 2019.12.25

Todo 예제에서 무작정 각 component에 style을 적용하는 코드를 추가했었습니다. 

 

이제 React native의 뷰 구조 분리 및 style 적용에 대해서 알아보도록 하겠습니다. 

 

style을 적용하는 방법은 직접 태그에 스타일 속성을 추가하는 인라인 스타일과 StyleSheet를 통한 정의 방식이 있습니다.

* 여러 component에 적용되는 스타일은 StyleSheet를 이용하여 적용하고 특정 component에 적용해야 하는 몇몇 속성들은 인라인 스타일을 사용하여 스타일 코드를 정리할 수 있다.

 

- 스타일을 한번에 여러개 적용 할 때는 <Text style={[ style, style ]}>과 같이 배열 형태로 작성

- 스타일을 여러개 적용 할 때 중복되는 property는 마지막의 것으로 적용 됨(앱 성능을 위해 중복 적용 주의)

- 스타일을 따로 정의하면 코드의 가독성이 올라가고 재사용으로 인한 전체적인 컨셉 수정에 용이(가독성 있는 스타일 네이밍 필요)

- component.js , style.js로 스타일 코드를 따로 분리하여 export, import하여 적용할 수 있음

- 스타일 속성에서는 전체 속성(borderWidth: 3)보다 세부 속성(borderLeftWidth:1)이 우선 순위가 높음

 

그럼 버튼을 눌렀을때 전체 테마를 바꾸는 예제를 스타일 파일을 분리하여 구현해 보도록 하겠습니다. 

 

https://github.com/action-intent/ReactNative/tree/master/Style

* AppStyle.js를 진입점으로 설정해주세요.

난해할 수 있는 부분은 코드에 주석으로 추가하였습니다. (참고로 react의 JSX 코드에는 주석을 넣을 수가 없습니다..)

 

 

 

 

 

 

 

 

위 코드를 다운받아 실행해 보면 White 버튼을 누르면 container와 button의 색이 바뀌고 button label도 변경됩니다.

 

 

 

 

 

 

 

 

 

 

 

이렇게 구현했을 때의 장점은 구현 그대로 앱의 전체 테마를 손쉽게 변경 할 수 있다는 점이고 스타일 코드를 모아 놓아 로직 코드가 간단해 지고 스타일 변경 시 확인해야 할 부분이 분명해 진다는 점입니다.

* 코드의 구조적 분리는 코드의 readability를 높여 유지 보수를 쉽게 하며 협업이 요구되는 프로젝트에서 큰 이점이 된다는 당연한 얘기를 해봅니다.

 

View component에 스타일 적용

view component는 html의 div 태그와 비슷한 것이라 생각하시면 됩니다. 

여기엔 다양한 스타일 속성을 적용할 수 있습니다. 프로필 카드 View 예제를 만들어 보면서 하나하나 알아 보도록 하겠습니다. 

* 같은 github에 AppView.js를 참고하세요.

 

1. 배경색 설정 : backgroundColor로 값은 rgb, rgba(알파), hsl(색상, 채도 명도), hsla, transparent, saturation, lightness

2. 테두리 설정 : borderColor, borderRadius(둥근테두리), borderStyle, borderWidth (e.g borderTopColor: 'red')

* 현재 borderStyle dashed, dotted 속성에 borderWidth를 부분 설정하려고 하면 오류가 난다고 하네요? 그런듯 합니다.

3. Image 가져오기 : <Image> 태그를 이용하고 source={require('image path')} 형태로 불러옴(import에 Image component 추가)

 

 

 

 

 

 

 

 

지금까지 반영한 스타일 코드를 띄우면 다음과 같습니다. 

아.. 뭔가 되려고 함..

 

 

 

 

 

 

 

 

 

 

 

4. margin, padding, position

* 모든 기능이 그렇지만 스타일 적용 후 iOS, 안드로이드 모두 테스트를 해봐야 합니다.  같은 속성이 플렛폼에 따라 다르게 표현될 수 있기 때문..

- margin은 부모 요소와의 간격 padding은 자식 요소와의 간격

- {position: 'absoulte', right: 0, bottom: 0} 부모 요소의 오른쪽 아래에 위치

 

 

 

 

 

 

 

 

cardContainer, cardImageContainer에 alignItems, marging, padding 속성을 추가하고 훨씬 보기 편안해진 모습입니다.

 

 

 

 

 

 

 

 

 

 

 

5. Text style

Text와 위에서 배운 View의 속성은 공통점이 많습니다. View의 대부분의 속성을 Text에서도 사용할 수 있습니다. 

- font의 경우 플렛폼 마다 지원하는 종류가 다를 수 있음. ...platform.select로 플렛폼 별로 스타일 속성을 설정할 수 있음 

- fontSize, fontStyle, fontWeight등의 속성을 사용할 수 있음

 

 

 

 

 

 

 

 

텍스트 스타일 속성을 통해 텍스트가 훨씬 보기 좋아졌음을 알 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

6. 텍스트 장식

텍스트 장식은 플렛폼 마다 지원하는 속성이 다를 수 있습니다.

- lineHeight: Text 높이 지정 

- textAlign: Text 수평정렬

- textDecorationLine: 밑줄, 취소선 등

- textDecorationColor, textDecorationStyle은 iOS만 지원하는 속성으로 밑줄등의 스타일 속성

- textShadowColor, textShadowOffset(음영의 위치), textShadowRadius(투명도)

 

 

 

 

 

 

 

 

 

마지막으로 name에 그림자 속성을 추가해 보았습니다. 작지만 큰 차이가 느껴지는 속성입니다. 

 

 

 

 

 

 

 

 

 

 

지금까지 component의 기본 스타일을 적용하는 방법에 대해서 알아 보았습니다.

 

다음 포스팅에서는 고급 스타일링 기법에 대해서 알아보도록 하겠습니다. 

'React native' 카테고리의 다른 글

Navigation  (0) 2020.01.02
고급 Style  (0) 2019.12.29
Todo 2  (0) 2019.12.25
Todo 1  (0) 2019.12.25
State, Props, Lifecycle  (0) 2019.12.25

지난 Todo1에서 todo item을 state에 추가하는 것 까지 진행 되었습니다. 요번엔 추가된 item이 렌더링 되어 리스트에 추가되는 것을 포함하여 Todo 예제를 마무리 해보도록 하겠습니다. 

 

1. Todo.js, TodoList.js 추가, App.js에 TodoList 추가

- 하나의 todo 아이템을 표현하는 component

- todos.map을 통해 각각의 todo component를 만들고 key, todo를 props로 전달

- const { inputValue, todos } = this.state  todos를 props로 전달하기 위해 추가

- <TodoList todos={todos} />  TodoList추가 todos를 props로 전달

 

 

 

 

 

 

 

전과는 달리 todo 입력 후 submit을 누르면 todo list에 추가 되는 것을 볼 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2. Todo item에 delete, complete button 달기

- App.js에 deleteTodo, toggleComplete 메서드를 추가

- 추가된 메서드를 클래스 생성자에서 바인딩

 

3. TodoButton.js 파일 생성

- 버튼 component는 props에 따라 delete, complete 버튼으로 전환된다.

 

4. App.js > TodoList.js > Todo.js 로 deleteTodo, togglecomplete props 전달

- App.js의 <TodoList>에 toggleComplete, deleteTodo를  props로 전달

- TodoList.js의 <Todo>에 toggleComplete, deleteTodo를  props로 전달

- Todo.js에 Done, Delete <TodoButton> 추가 (import TodoButton ...)

 

 

 

 

 

 

 

Todo를 추가하고 Done을 누르면 버튼 스타일이 변경됨

Delete 버튼을 누르면 Todo가 삭제 됨

 

 

 

 

 

 

 

 

 

 

 

 

 

5. TabBar.js추가

- App.js에 type 속성을 설정하는 setType 메서드 추가

- TabBar.js는 App.js로부터 setType, type props를 받는다.

- <TabBarItem>의 border props는 왼쪽 테두리 스타일 추가 여부

 

6. TabBarItem.js추가

- selected,border 등 props의 값에 따라 style을 지정

- type과 title props이 같으면 텍스트 스타일을 bold로 지정

 

7. App.js에 TabBar component 추가

- import TabBar

- TodoList에 type props추가

- type, setType props와 함께 <TabBar>추가

 

8. TodoList.js에 type filter 추가

- type, todos props를 이용하여 todos 목록을 complete의 값에 따라 필터링하는 getVisibleTodos 메서드 생성

- getVisibleTodos를 호출하여 todos의 목록을 갱신 하도록 호출

 

 

 

 

 

 

 

화면 하단에 TabBar가 생성되었고 Active, Complete에 따라 Todo 목록이 필터링 됨

 

 

 

 

 

 

 

 

 

 

 

 

 

여기까지 간단?한 할 일 관리 서비스를 React native로 만들어 보았습니다. 

 

이정도 예제만 완벽하게 이해했다면 이를 응용하여 다른 서비스도 충분히(수많은 검색과 삽질을 동반) 만들 수 있다고 생각되네요.

'React native' 카테고리의 다른 글

고급 Style  (0) 2019.12.29
Style  (0) 2019.12.27
Todo 1  (0) 2019.12.25
State, Props, Lifecycle  (0) 2019.12.25
Project 생성 및 빌드  (0) 2019.12.25

+ Recent posts