Sangil's blog

https://github.com/ChoiSangIl Admin

reactNative 캘린더(달력) 만들기 DEV / REACT NATIVE

2020-06-17 posted by sang12


reactNative를 이용해서 달력 만드는 방법을 알아보겠습니다. 아이폰과 안드로이드를 전부 지원 할 수 있는 라이브러리를 찾았는데 여기 있네요 :)  -> https://github.com/wix/react-native-calendars. 해당 깃허브를 참조하여 진행하였습니다.

github 예제 : https://github.com/ChoiSangIl/react-native-calendar-test

일단 프로젝트를 만들어야 겠죠?
npx react-native init calendarTest 명령어로 프로젝트를 생성합니다.

그리고 npm을 통해서 해당 라이브러리를 받아옵니다 

$ npm install --save react-native-calendars

이제 달력을 불러와 봅시다 :). 

-App.js

import React, { Component } from 'react'
import {Calendar, CalendarList, Agenda} from 'react-native-calendars';

class App extends Component {
  render() {
     return (
      <Calendar
        // Initially visible month. Default = Date()
        current={'2012-03-01'}
        // Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined
        minDate={'2012-05-10'}
        // Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined
        maxDate={'2012-05-30'}
        // Handler which gets executed on day press. Default = undefined
        onDayPress={(day) => {console.log('selected day', day)}}
        // Handler which gets executed on day long press. Default = undefined
        onDayLongPress={(day) => {console.log('selected day', day)}}
        // Month format in calendar title. Formatting values: http://arshaw.com/xdate/#Formatting
        monthFormat={'yyyy MM'}
        // Handler which gets executed when visible month changes in calendar. Default = undefined
        onMonthChange={(month) => {console.log('month changed', month)}}
        // Hide month navigation arrows. Default = false
        hideArrows={true}
        // Replace default arrows with custom ones (direction can be 'left' or 'right')
        renderArrow={(direction) => (<Arrow/>)}
        // Do not show days of other months in month page. Default = false
        hideExtraDays={true}
        // If hideArrows=false and hideExtraDays=false do not switch month when tapping on greyed out
        // day from another month that is visible in calendar page. Default = false
        disableMonthChange={true}
        // If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday.
        firstDay={1}
        // Hide day names. Default = false
        hideDayNames={true}
        // Show week numbers to the left. Default = false
        showWeekNumbers={true}
        // Handler which gets executed when press arrow icon left. It receive a callback can go back month
        onPressArrowLeft={substractMonth => substractMonth()}
        // Handler which gets executed when press arrow icon right. It receive a callback can go next month
        onPressArrowRight={addMonth => addMonth()}
        // Disable left arrow. Default = false
        disableArrowLeft={true}
        // Disable right arrow. Default = false
        disableArrowRight={true}
        // Disable all touch events for disabled days. can be override with disableTouchEvent in markedDates
        disableAllTouchEventsForDisabledDays={true}
        /** Replace default month and year title with custom one. the function receive a date as parameter. */
        renderHeader={(date) => {/*Return JSX*/}}
      />
     )
   }
 }
export default App;


워매 형님 무슨 달력하나 만드는데 옵션이 저렇게도 많습니까... 생각해보니 달력에 들어가는 기능들이 많을거같긴 하네요 :). 그런데 깃허브 소스를 참고해서 저와 같이 진행을 하셨다면, 저와 같은 화면을 보고 있겠죠?. 흰화면에 이상하게 나오고 도대체 위에 달력은 어디에 있지? 

요렇게 흰화면에 흰글씨냐 뭐냐..저게 이상한게 하나 떠있을테니까요 뭔가 깔끔한 달력 화면을 원했는데 말이죠 :). 그래도 떡하니 달력하나 나오는 거지만 이쁘게 나오게 변경해봅시다. 

화면이 위로올라가서 달이 안나오나..? 라는 생각에 View안에 넣어서 스타일로 paddingTop을 줘봤습니다. 하지만 여전히 달은 나오지 않았습니다.. 그래서 설정을 하나하나 변경하다보니 renderHeader를 주석처리해주니 정상적으로 나오네요. 그 외에도 current와 minDate, maxDate를 현재기준으로 변경해줬고 showWeekNumbers등을 수정해줬습니다. 

-변경한 App.js

import React, { Component } from 'react'
import {View} from 'react-native';
import {Calendar, CalendarList, Agenda} from 'react-native-calendars';
import {LocaleConfig} from 'react-native-calendars';

LocaleConfig.locales['fr'] = {
  monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'],
  monthNamesShort: ['Janv.','Févr.','Mars','Avril','Mai','Juin','Juil.','Août','Sept.','Oct.','Nov.','Déc.'],
  dayNames: ['일요일','월요일', '화요일','수요일','목요일','금요일','토요일'],
  dayNamesShort: ['일', '월','화','수','목','금','토'],
  today: 'Aujourd\'hui'
};
LocaleConfig.defaultLocale = 'fr';

class App extends Component {
  render() {
     return (
      <View style={{ paddingTop: 50, flex: 1 }}>
        <Calendar
        // Initially visible month. Default = Date()
        current={'2020-06-07'}
        // Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined
        minDate={'2020-01-01'}
        // Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined
        maxDate={'2020-12-31'}
        // Handler which gets executed on day press. Default = undefined
        onDayPress={(day) => {console.log('selected day', day)}}
        // Handler which gets executed on day long press. Default = undefined
        onDayLongPress={(day) => {console.log('selected day', day)}}
        // Month format in calendar title. Formatting values: http://arshaw.com/xdate/#Formatting
        monthFormat={'yyyy MM'}
        // Handler which gets executed when visible month changes in calendar. Default = undefined
        onMonthChange={(month) => {console.log('month changed', month)}}
        // Hide month navigation arrows. Default = false
        hideArrows={true}
        // Replace default arrows with custom ones (direction can be 'left' or 'right')
        renderArrow={(direction) => (<Arrow/>)}
        // Do not show days of other months in month page. Default = false
        hideExtraDays={true}
        // If hideArrows=false and hideExtraDays=false do not switch month when tapping on greyed out
        // day from another month that is visible in calendar page. Default = false
        disableMonthChange={true}
        // If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday.
        firstDay={1}
        // Hide day names. Default = false
        hideDayNames={false}
        // Show week numbers to the left. Default = false
        showWeekNumbers={false}
        // Handler which gets executed when press arrow icon left. It receive a callback can go back month
        onPressArrowLeft={substractMonth => substractMonth()}
        // Handler which gets executed when press arrow icon right. It receive a callback can go next month
        onPressArrowRight={addMonth => addMonth()}
        // Disable left arrow. Default = false
        disableArrowLeft={true}
        // Disable right arrow. Default = false
        disableArrowRight={true}
        // Disable all touch events for disabled days. can be override with disableTouchEvent in markedDates
        disableAllTouchEventsForDisabledDays={true}
        /** Replace default month and year title with custom one. the function receive a date as parameter. */
        //renderHeader={(date) => {/*Return JSX*/}}
        />
      </View>
     )
   }
 }

export default App;

자 이제, 다시 에뮬레이터를 봅시다. 달력이 조금 더 이뻐졌군요 :). 그리고 해당 일자를 클릭하면 로그로 년도와 날자등이 나오는 것을 확인 할 수 있습니다~!


그런데 달력을 눌렀을때, 로그로만 나오니 조금 누르는 맛이 나지 않네요. toast를 이용해서 눌러진 일자를 출력해봅시다!

-App.js 수정

//ToastAndroid 추가
import {View, ToastAndroid} from 'react-native';
//..생략 //onDayPress 함수 수정
onDayPress={(day=> {
    console.log('selected day'day)
    ToastAndroid.showWithGravity(
      day.dateString,
      ToastAndroid.SHORT,
      ToastAndroid.CENTER
    );   
}}

자 이제 일자를 눌러볼까요? 잘나오네요 :) 여기까지 reactNative에서 달력만드는 방법을 알아봤습니다.

#reactNative 달력이 이상하게나와요 #reactNative 달력 흰색 #reactNative 달력 클릭 이벤트 #reactNative Toast 달력

kim
2021-10-11 18:18:14

요일 색상 변경하는법도 알 수 있을까요?

답글
kim
2021-10-12 07:58:06

예를 들어 일요일만 빨간색으로 변경하는 방법이요

답글
REPLY