블로그 이미지
'무른모'란 부드럽다라는 뜻을 가진 '무르다'라는 말과 도구, 연장을 뜻하는 '연모'라는 순 우리말의 합성어로 소프트웨어를 말합니다. seanhigher

카테고리

분류 전체보기 (161)
Blog srart (16)
Dev Center (94)
Real Life (13)
Mac life (21)
Naver life (17)
Total633,812
Today36
Yesterday88
php 에 관한 환경설정은 모두 php.ini 파일에 포함되어 있다. php.ini 파일만 잘 다룰 줄 안다면 php 를 설정하고 사용하는데는 전혀 어려움이 없을 것이다. 물론 그렇지 않아도 약간의 부담을 감수하고 사용하는데는 큰 무리가 없긴 하지만...


timezone 설정하기.
php 스크립트 중에서 시간과 관련된 'date()' 와 같은 함수를 사용할 경우 다음과 같은 메세지가 나올 경우가 있다.

Warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Seoul' for 'KST/9.0/no DST' instead in /Users/seanhigher/Sites/PHPinHTML.php

어렵지 않게 짐작했겠지만, 시간과 관련된 설정이 되어 있지 않을 경우 나오는 메세지이다. 물론 자동적으로 위치를 검색해서 제대로 된 시간이 나오긴 하지만, 위와 같은 메세지는 그리 달갑지가 않다. 위의 메세지가 더이상 나오지 않게 하기 위한 방법으로는 두가지가 있는데 하나는 'date()' 함수를 사용하기전에 'date_default_timezone_set('Asia/Seoul');' 와 같이 timezone 을 설정해주는 것이다. 간단하게 해결할 수 있기는 하지만, 매번 'date()' 함수가 사용되는 페이지마다 선언한다는 것은 상당히 불필요한 작업이 될 수 있다. 두번째 방법은 'php.ini' 파일에서 설정해 주는 것이다. 첫번째 방법이 일회용이라고 하면, 두번째 방법은 한번만 수고하면 영원히 사용할 수 있는 영구적인 방법이다. 'php.ini' 파일은 php 에 관련한 환경설정들이 들어있는 환경설정 파일이다. php.ini 파일이 있는곳은 각 플랫폼마다 다르다. 하지만, phpinfo() 함수를 통해 나타난 php 의 정보중에 Configuration File (php.ini) Path 항목을 확인하면 php.ini 파일이 있는 곳을 알 수 있다.


그림1. 폴더로 이동

'/etc' 폴더의 경우 숨김 폴더로 되어 있기 때문에 파인더에서 클릭을 하여서 이동하는 방법으로는 이동이 불가능하다. 위 그림과 같이 파인더의 '이동' -> '폴더로 이동' 항목을 선택하여 '/etc' 폴더로 이동한다.


그림2. '/etc' 폴더

하지만, 아무리 찾아보아도 'php.ini 파일을 찾을 수가 없다. PHP5 버전 이후 부터는 'php.ini' 파일 대신에 'php.ini-dist', 'php.ini-production', 'php.ini.default' 와 같은 파일 이름을 사용하기도 한다. 이런 경우에는 이 파일을 'php.ini' 파일로 복사하여 사용하면 된다. 이제 준비된 'php.ini' 파일을 살펴보면 date.timezone 항목이 비어있는 것을 볼 수 있다.


그림3. php.ini 파일

위 화면의 박스안에 있는 부분에 다음의 소스를 넣으면 된다.

;date.timezone = Asia/Seoul

timezone 항목으로 들어가는 인자는 http://php.net/timezone 페이지에서 확인할 수 있다. 이제 date() 함수를 사용하여도 위와 같은 warning 메세지를 보지 않아도 될 것이다.

'Dev Center > PHP start' 카테고리의 다른 글

String 타입의 변수 사용하기.  (0) 2010.05.02
PHP 의 변수.  (0) 2010.05.01
timezone 설정하기.  (0) 2010.04.30
PHP 에 무슨 문제라도??  (0) 2010.04.29
HTML 과 PHP 함께 사용하기.  (3) 2010.04.27
eclipse에 PDT 설치하기.  (0) 2010.03.27
Posted by seanhigher

댓글을 달아 주세요

어렵게 PHP 를 설치하였다. 그런데 이상하게도 제대로 작동하지 않는 PHP 문서들... 게다가 제대로 나타나지 않는 한글들은 무슨 문제가 있어서 그런건지... PHP 를 설치한 후에 제대로 사용하기 위해서는 기본적으로 해 주어야 별 문제없이 사용할 수 있는 설정들이 있다.


꼭 확장자를 .php로만 해야 하는걸까?
스크립트 언어인 PHP 는 HTML 태그안에 포함되는 형태로 사용된다. php 파서는 HTML 문서내의 php 소스가 들어간 부분의 태그를 보고, 그것이 PHP 스크립트라고 생각하고 해석을 시작하게 되는 것이다. 그래서 사실 확장자가 html 이던 php 이던 똑같을 수 밖에 없는 것이다. 단지 주로 쓰여진 부분이 어떤 것인가, 또는 개발자의 스타일에 전적으로 맡겨질 수 밖에 없는 부분이다. 하지만, 분명 phpinfo() 함수가 실행되는것을 봐서는 문제업이 PHP 가 설치되었는데, 확장자를 html 로 하였을때는 실행이 되지 않는 경우가 있다. 이것은 아파치 서버에서 PHP 모듈이 읽을 수 있는 문서에 html이 포함되어 있지 않기 때문이다.


확장자가 html 일때도 php 스크립트가 실행되도록 하기.
PHP 는 아파치 서버에 모듈 형태로 작동하기 때문에 PHP 모듈이 어떤 문서를 인식하는지를 설정하기 위해서는 아파치의 설정 파일인 'httpd.conf' 파일을 수정해야 한다.


그림1. 폴더로 이동


그림2. /etc 폴더

먼저 파인더를 실행한 후 '이동' -> '폴더로 이동' 을 선택하여 '/etc' 폴더로 이동한다. /etc 폴더는 'HardDisk \ private \ etc' 에 위치해 있지만, 중요한 파일들이 많이 있는 숨김 폴더이기 때문에 마우스를 클릭하여 이동하는 방식으로는 접근이 불가능하다. '\etc' 폴더 아래에 있는 'apache2' 폴더를 보면 우리가 찾는 'httpd.conf' 파일이 있는것을 볼 수 있다. 이 파일을 열어서 html 문서도 php 파서가 읽어들일 수 있돌고 설정을 해주어야 한다.


그림3. 설정 추가

위 그림처럼 빨간 네모에 있는 내용을 추가하면 된다. 꼭 위 화면에 나온 위치가 아니라도 상관없다. 자신이 원하는곳에 써 넣도록 한다.

# And for PHP 5.x use:
#
AddType application/x-httpd-php .php .phtml .php5 .html


x-httpd-php 다음에 나오는 확장자를 가진 문서들을 php 파서가 인식하도록 하는 것이다. 확장자 앞에 닷(.)을 빼먹지 말고 써넣어야 한다. 위의 소스를 입력하였다면 저장을 하고 아파치 서버를 다시 시작하면 html 확장자를 가진 문서에서도 문제없이 php 스크립트가 작동되는 것을 볼 수 있을 것이다.

'Dev Center > PHP start' 카테고리의 다른 글

PHP 의 변수.  (0) 2010.05.01
timezone 설정하기.  (0) 2010.04.30
PHP 에 무슨 문제라도??  (0) 2010.04.29
HTML 과 PHP 함께 사용하기.  (3) 2010.04.27
eclipse에 PDT 설치하기.  (0) 2010.03.27
PHPeclipse 설치하기.  (2) 2010.03.15
Posted by seanhigher

댓글을 달아 주세요

PHP 는 PHP 이고 HTML 은 HTML 인데... 이 둘을 함께 사용하려면 어떻게 해야 할까? PHP는 ASP, JSP와 같은 스크립트 형태의 언어이기 때문에 HTML 태그에 내장되는 형태로 사용이 된다. PHP를 선언하는 태그를 HTML 문서에 포함시킨후, 태그 안에 PHP 소스를 넣으면 된다.



PHP임을 알리는 HTML 태그.
HTML 문서에 PHP임을 알리는 태그는 매우 간단하다. '<?php ?>' 또는 '<? ?>' 이다. 가운데 빈 공간에 PHP 스크립트 코드를 써 넣으면 되는 것이다. 사실 HTML 문서나, PHP 문서나 똑같은 웹 문서일 뿐이다. 확장자의 이름만 다를 뿐이다. HTML 과 PHP 문서를 구분짓는 것은 그 안에 사용되는 태그를 어떻게 사용하느냐이다. 확장자명을 PHP로 한다고 할찌라도 일반적인 HTML 태그를 사용한 소스만을 사용한다면 HTML 문서와 똑같이 작용할 뿐이다. 그렇기 때문에 PHP 로 시작하는 문서는 보통 '<?' 로 시작하게 된다.


HTML 문서안에 PHP 포함시키기.
HTML 문서에 PHP 소스를 포함시키기 위해서는 '<? ?>' 태그안에 PHP 소스를 작성하면 된다.

<PHPinHTML.html>
<HTML>
  <HEAD>
    <TITLE>HTML 안에 PHP</TITLE>
  </HEAD>
  <BODY>
    지금 시간은 <b> <? echo date("Y-m-d H:i:s") ?> </b> 입니다.
  </BODY>
</HTML>


'echo' 는 C 언어의 printf문과 같은 역할을 한다. 다음에 나오는 인자를 화면에 출력해주는 역할을 한다. date() 함수는 현재의 날짜, 시간을 출력해주는 함수이다. 위의 'PHPinHTML.html' 문서를 실행하면 다음과 같은 결과가 나오게 된다.


그림1. HTML 안에 PHP

Warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Seoul' for 'KST/9.0/no DST' instead in /Users/seanhigher/Sites/PHPinHTML.php on line 8

만약 위와 같은 warning 메시지를 보게된다면 타임존이 설정되지 않은것이다. 아래와같이 타임존을 설정해주는 소스를 추가해주면 에러메세지가 사라질 것이다.

<PHPinHTML.html>
  <HEAD>
    <TITLE>HTML 안에 PHP</TITLE>
    <? date_default_timezone_set('Asia/Seoul'); ?>
  </HEAD>


PHP 문서안에 HTML 포함시키기.
반대로 PHP 문서안에 HTML 태그를 포함시킬 수 도 있다. PHP 는 이렇게 유연한 방식으로 개발자들을 대하기 때문에 개발자의 사용습관에 따라 편한대로 사용할 수 있다. PHP 문서안에 HTML 태그를 포함시키기 위해서는 'echo' 함수를 사용할 수 있다. echo 는 C 에서의 printf 문과 마찬가지로 이후의 내용을 출력하는 역할을 하기 때문에 echo 의 인자로 HTML 태그를 포함시킴으로 HTML 태그를 표현할 수 있게 된다.

<HTMLinPHP.php>
<?
  echo "<HTML><HEAD><TITLE>PHP 안에 HTML</TITLE></HEAD>
  <BODY>지금 시간은 <b>";
  echo date("Y-m-d H:i:s");
  echo "</b> 입니다.</BODY></HTML>";
?>


위의 소스코드를 실행하면 'PHPinHTML.html' 문서를 실행한것과 같은 결과를 보게 될 것이다.


그림2. HTMLinPHP.html

PHP 를 사용하는 방법은 다양하다. 하지만 다양하다고 해서 편하다는 것은 아니다. 분명, 일반적인 위지윅 방식의 HTML 편집기와 함께 사용하려고 한다면 어려움이 있기 마련이다. 하지만 이런 문제를 단번에 해결하면서도 좀더 효율적으로 PHP 소스를 활용할 수 있는 방법이 있다. include() 함수가 그 방법이다!


통째로 포함시키기.
수십페이지에 달하는 웹 페이지를 제작하려고 하는 개발자가 있다. 하지만, 모든 페이지가 대부분 같은 폼을 가지고 있다. 똑같은 작업을 수십번 반복해야 하는 것이다. 만들때는 새로 만들어서 복사하면 된다고 하지만, 수정을 해야 할때는 대책없이 수십개의 문서를 일일이 수정해 주어야 한다. 이럴때, 템플릿을 활용하면 훨씬 수월하게 작업을 하고, 웹페이지 유지보수를 할 수 있다. 똑같은 형식을 갖는 부분을 템플릿으로 만들고 수십개의 문서에 그것을 포함시키는 형식으로 적용을 시키는 것이다. 수정을 할 때는 템플릿만 수정을 하게 되면 모든 템플릿을 포함한 모든 문서에 똑같이 적용이 되는 것이다.


그림3. 템플릿의 활용

템플릿은 HTML 문서로 작성하여도, PHP 문서로 작성하여도 무방하다. 템플릿 문서를 포함하고자 하는 문서에 '<? include "템플릿 문서"; ?>' 와 같은 형식을 취하면 된다.

<TimeTemplate.php>
<?
  echo "지금 시간은";
  echo date("Y-m-d H:i:s");
  echo "입니다";
?>

<documentA.html>
<HTML>
  <HEAD>
    <TITLE>템플릿의 활용</TITLE>
  </HEAD>
  <BODY>
  <? include "TimeTemplate.php"; ?>
  </BODY>
</HTML>


위의 두개의 파일을 실행하면 다음과 같이 실행되는 것을 알 수 있다.


그림4. documentA.html (include TimeTemplate.php 포함)

위에서 설명한 예제는 간단하지만, 좀더 큰 규모의 웹 페이지를 제작하게 될 경우에 템플릿을 사용하여 효율성을 극대화 하는 것은 꼭 필요한 기능이다.



'Dev Center > PHP start' 카테고리의 다른 글

PHP 의 변수.  (0) 2010.05.01
timezone 설정하기.  (0) 2010.04.30
PHP 에 무슨 문제라도??  (0) 2010.04.29
HTML 과 PHP 함께 사용하기.  (3) 2010.04.27
eclipse에 PDT 설치하기.  (0) 2010.03.27
PHPeclipse 설치하기.  (2) 2010.03.15
Posted by seanhigher

댓글을 달아 주세요

  1. 2010.04.28 00:54  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  2. 2015.12.31 22:34 신고 소울라이어  댓글주소  수정/삭제  댓글쓰기

    제가 개념이 없어서 그러는데요.
    티스토리 블로그에 글쓰기를 한다음 HTML모드에서 이 코드를 적으면요
    <HTML>
    <HEAD>
    <TITLE>HTML 안에 PHP</TITLE>
    </HEAD>
    <BODY>
    지금 시간은 <b> <? echo "ㅇㅇㅇㅇㅇㅇㅇ"; ?> </b> 입니다.
    </BODY>
    </HTML>

    안나오는게 정상인가여?

아이폰 개발을 하기 위해 필요한것은 개발 도구와, 개발한 애플리케이션을 실행해 볼 수 있는 아이폰이나, 아이팟 터치일 것이다. 하지만, 아이폰/아이팟 터치가 없다면?? 컴퓨터는 누구나가 다 가지고 있기 때문에 해킨토시를 하던, VMware를 통해 설치하는 등의 방법을 통해 설치 할 수 있지만, 없는것을 만들어 낼 수는 없는 노릇이다. 그리고 매번 동기화 시켜서 테스트 할 수도 없는것이고... 다른 개발 툴들도 마찬가지겠지만, 아이폰 SDK에는 실제 실행환경과 매우 유사한 iPhone simulator 가 준비되어 있다.




아이폰 시뮬레이터 실행하기.
Xcode 로 애플리케이션을 작성하고 'Run and Build' 버튼을 누르면 소스코드가 빌드되고, 자동으로 아이폰 시뮬레이터가 실행이 된다. 그리고 지금 개발중인 애플리케이션이 실행한 상태의 화면이 나타나게 된다. 애플리케이션은 실행하지 않은채로 아이폰 시뮬레이터만 실행해 보고 싶다면 HardDisk -> Developer -> Platforms -> iPhoneSimulator.platform -> Developer -> Applications 의 순서로 폴더를 따라가다 보면 'iPhone Simulator' 실행 파일을 만날 수 있다. 이 파일을 더블 클릭하면 아이폰 시뮬레이터가 실행된다.


손가락이 없다면 마우스로...
아이폰을 가장 잘 활용하기 위한 도구는 우리 모두가 가지고 있는 손가락이다. 하지만 아쉽게도 컴퓨터에는 손가락이 없다. 대신에 마우스라는 친근한 도구가 우리에게 있다. 마우스와 마우스의 버튼은 우리가 손가락으로 아이폰에 입력할 수 있는 대부분의 입력을 충분히 입력할 수 있도록 해준다.


그림1. 아이폰 시뮬레이터의 입력

Mouse Click : 마우스를 원하는 곳에 이동한 후 클릭하는 것을 손을 아이폰의 화면에 대는 것과 같다고 할 수 있다. 무엇인가를 선택할 때 사용되고, 버튼 형식의 객체를 컨트롤 할 수 있다.
Mouse double Click : 마우스를 더블클릭하는 것은 손가락으로 빠르게 두번을 탭하는 것과 같다. 취소를 하거나, 화면 전환을 할 때, 탭 이외의 추가적인 입력이 필요할 때 사용 할 수 있다.
Mouse Click & Drag : 마우스를 클릭한 상태에서 드래그를 하는 것은 손가락을 아이폰의 화면에 대고 끄는것과 같은 역할을 하게 된다. 매우 큰 화면을 볼 때 이리저리 움직일 때 사용하거나, 화면 전환에 유용하게 쓰이는 제스쳐이다.
'option' + Mouse Click & Drag : 'option' 키를 누른 상태에서 마우스를 클릭하면 위의 화면과 같이 두개의 원이 생기게 되는데 이것은 두개의 손가락을 의미한다. 이것을 드래그하면 손가락의 간격을 줄이거나 늘이거나 할 수 있는데, 화면을 확대하거나 축소할때 손쉽게 사용하는 제스쳐이다.


아이폰 흔들기.
아이폰의 주요 특징의 하나는 위치와 방향에 대한 감각이 뛰어나다는 것이다. 아이폰을 눞이거나 세우거나하는 방식으로 좀더 효율적인 애플리케이션 사용환경을 만들어 줄 수 있고, 좌우로 기울이면서 애플리케이션을 제어할 수 있다. 그리고 흔들기도 가능하다!


그림2. 아이폰을 옆으로 Rotate 상태.

아이폰을 오른쪽으로, 또는 왼쪽으로, 아니면 뒤집어 놓으려면 메뉴를 이용해야 한다. 아이폰을 움직이는 메뉴들은 Hardware 메뉴에서 볼 수 있다.


그림3. Hardware 메뉴

Hardware 메뉴에서 'Rotate Left' 를 선택하면 아이폰이 왼쪽으로 90도 회전한다. 반대로 'Rotate Right' 를 선택하면 아이폰이 오른쪽으로 90도 회전하게 된다. 아이폰을 뒤집어 놓고 싶다면 한쪽 방향으로 두번 회전을 하면 180도를 회전하여 뒤집어진 아이폰의 모습이 된다. 단축키로 '사과' + '->' 또는 '사과' + '<-' 키를 사용할 수도 있다. 그리고 그 아래에 있는 'Shake Gesture' 는 아이폰을 흔들어주는 기능이다. 실제 에니메이션으로 아이폰이 흔들어지지는 않지만, 그 효과가 아이폰에 그대로 적용된다. 아이폰 애플리케이션을 제작하면서 흔들기 제스쳐를 포함시켰다면, 위 메뉴를 사용하여 테스트 해 볼 수 있다. 하지만 한가지 아쉬운 것은 중력센서를 컨트롤 하는 것은 아직 지원하지 않는다는 것이다.


그림4. 아이폰이 'Lock' 된 상태

아이폰에 달려있는 여러가지 버튼들을 사용하기 위해 클릭을 해보면... 아무것도 일어나지 않는다. 단지 가운데 떡하니 자리잡고 있는 홈버튼만이 작동할 뿐이다. 아직 아이폰 시뮬레이터에서는 볼륨조절버튼, 전원버튼, 락버튼등 시뮬레이터에서 보이는 버튼들을 누르는것이 가능하지 않다. 한가지 'Lock' 버튼은 hardware 메뉴에서 선택하여 실행할 수는 있다.


아이폰 시뮬레이터 리셋하기.
맨 처음 'Hello world!' 출력하기 프로젝트 부터, 점점 진화하는 다양한 프로젝트를 개발하면서 공부를 하다보면, 벌써 수많은 어플리케이션이 나도모르는 사이에 아이폰 시뮬레이터에 설치되어 있는것을 볼 수 있다. 문제는 이미 삭제한 애플리케이션까지 설치되어 있다는 것이다.

그림5. 아이폰 시뮬레이터 리셋

아이폰 시뮬레이터는 Xcode 프로젝트에서 빌드하는 모든 애플리케이션을 설치하게 된다. 그렇게 많은 애플리케이션이 설치되면 나중에는 점점 시뮬레이터에 무리가 가게 된다. 결국엔 더이상 프로젝트를 생성할 수 없는 단계에 까지 이르게 되는 것이다. 하지만, 이럴때를 위해 준비된 것이 있다. 바로 리셋! 하드웨어를 포멧하는 것과 같은 작업을 아이폰 시뮬레이터에도 하는것이 가능하다. 메뉴의 iPhone Simulator -> Reset Content and Settings... 를 차례로 선택하면 아이폰 시뮬레이터를 정말로 리셋할것인 확인을 한후 리셋을 한다. 리셋을 하고 나면 다시 쌩쌩하고 깨끗한 아이폰 시뮬레이터 환경에서 애플리케이션을 제작할 수 있을 것이다.

Posted by seanhigher

댓글을 달아 주세요

많은 사람들이 새로운 일을 하게될때면 계획을 세우곤 한다. 앞으로 이루어질 일들을 어떻게 할 것인가에 대해서 생각해보고 그 일을 실행한다면 그렇지 않을 때보다 훨씬 더 좋은 결과를 맞이하게 된다. 돈을 쓰는것도 마찬가지이다. 돈이 생기게 되면 그에 따른 예산계획을 세우고 사용한다면 낭비없는 튼실한 경제생활을 하게 될 것이다.


기록만 해서는 소용이 없다.
가계부를 작성하는 이유는 내가 돈을 어떻게 사용했는지 기록하기 위해서이다. 사용한 돈을 기록하면, 남아 있는 돈이 얼마인지 알 수 있다. 신용카드같이 직접적으로 돈이 나가지 않아 무분별하게 사용하는것을 방지 할 수 있는 것이다. 그렇다면 단순히 신용카드의 남발을 막기 위해서 가계부를 작성해야 할까? 돈이 어떻게 사용되는지 알기 위해서만? 이 두가지의 목적만 가지고 있다면 아직 가계부를 절반밖에 활용하지 못하는 사람이다. 가계부를 쓰는 진정한 목적은 돈을 쓰기전에 가계부를 작성하는 것이다.


돈을 쓰기 전에 쓰는 가계부?
쓰지도 않은 돈을 가계부에 적는다고 하니 쉽게 이해가 되지 않을 것이다. 물론 앞으로 사용할 돈을 내일 점심값 얼마, 모레 주유비 얼마 이런식으로 정확하게 기록한다는 것은 아니다. 그렇다면 어떻게 할까? 돈을 쓰기전에 가계부를 쓰는 방법은 바로 예산 계획을 세우는 것이다. 각각의 항목이나, 분류를 나누어 놓고 사용할 금액을 미리 정해 놓고 실제로 그 금액에 맞추어 생활을 해 나가는 것이다.


네이버 가계부에서 예산 계획 세우기.
예산계획을 세우기 위해서는 먼저 내가 어떻게 경제생활을 하고 있는지 아는것이 중요하다. 지난 한달동안 어떻게 돈을 사용했는지 기억해 보면 어느정도 알 수 있겠지만, 대충이라도 기억이 나지 않는다면 정확한 자가 진단을 위해서 두어달정도는 계획을 세우지 않은채로 가계부를 작성해 보는 것을 추천한다.


그림1. 예산 보기

네이버 가계부의 화면 왼쪽 아래를 보면 이달의 예산이라는 항목이 있다. 이것은 사용자가 작성한 예산에 어느정도 맞춰 돈을 사용하고 있는지를 간편하게 보여주는 항목이다. 물론 예산을 작성하지 않았다면 나타나지 않는다. 예산을 작성하기 위해서 '예산쓰기'항목을 클릭하도록 하자.


그림2. 예산쓰기

네이버 가계부의 예산쓰기 화면은 위와 같이 구성되어 있다. 크게 이전에 작성된 예산을 보여주는 왼쪽 부분과, 예산을 작성하는 오른쪽 부부분으로 나뉘어 진다. 왼쪽 부분을 보면 지난달에 세운 예산 계획과, 실제로 어떻게 돈을 사용했는지 비교를 해보며 볼 수 있다. 위의 3월달 예산에서는 무려 17만원이나 예산을 초과하여 사용하였다!! 지난 예산과 실 사용 금액을 잘 비교해 보면서 오른쪽 부분에 새로운 에산을 작성하도록 한다. 예산을 쓰고 계획한 예산이 얼마나 잘 지켜지고 있는지 확인하기 위해서는 윗부분에 '예산반성'탭을 클릭하여 이동하여 확인할 수 있다.


그림3. 예산 반성

'예산반성'에서는 약 6개월동안의 기간을 정하여 그동안 예산과 실 사용금액이 얼마나 차이나는지 한눈에 볼 수 있다. 예산 계획을 세우는데 있어서 가장 중요한 것은 예산 계획을 세우고 그것을 지키려고 노력하는 것이다. 자신의 노력만큼 조금식 조금씩 돈이 모이는 통장을 볼 수 있을 것이다.

Posted by seanhigher

댓글을 달아 주세요

돈을 절약하기 위해서 지출을 줄이려고 하는데, 어떤 부분에서 줄여야 할찌가 막막하기만 하다. 내가 쓰고 있는 돈들은 꼭 필요한곳에만 사용을 하고 있는 거 같은데... 각 지출의 내역마다 항목을 정해놓거나, 태그를 달아놓으면 쉽게 구별을 할 수가 있다. 스마트한 네이버 가계부에서는 가능하다!


분류의 기준?
그렇다면 가계부 항목을 작성하는데 있어서 기준으로 해야 할 것은 무엇일까? 분류를 하는데 있어서 기준이 될 수 있는 것은 다양하다. 사용한 장소에 따라 분류 할 수도 있고, 어떠한 목적으로 사용했는가에 따라 분류를 하거나, 현금/카드의 사용으로 분류할 수 있다. 이 여러가지 항목을 한번에 사용한다면 나중에 보고서를 볼때는 편리하겠지만, 입력을 할때는 너무 할것이 많아 귀찮아지기 쉽상이다. 적당히 꼭 필요한 부분으로 분류를 하도록 하는 것이 좋다. 네이버 가계부에서는 어떠한 목적에 따라 지출내역을 분류하는 기능을 제공한다. 그리고 사용자가 등록한 카드별로 지출 방법으로 분류 할 수 있다. 한가지 더 추가해서 여행등의 특별한 지출항목을 태그로 설정해 줄 수 있다.


현금으로 사용했는가? 카드로 사용했는가?
요즘에는 현금으로 지출을 하는 경우가 많이 드물어 졌다. 노점상에서 간식거리나, 물품을 구입할 때를 제외하고는 거의 대부분 카드로 결제를 하게 된다. 신용을 보증할 수 없는 학생의 경우에도 체크카드를 대신하여 사용하곤 한다. 현금같은 경우는 그때마다 손에서 사라지기 때문에 돈의 흐름을 쉽게 느낄 수 있지만, 신용카드같이 다음달에 금액이 청구되거나, 할부로 지급하게 될 경우는 돈이 세는 줄도 모르고 펑펑 쓰기 마련이다. 이럴때는 카드 분류를 사용하면 현금의 흐름을 쉽게 파악할 수 있다.


그림1. 가계부 화면

위의 내용은 개인적인 가계부를 작성한 것이다. 중앙 아래부분에 2번 네모박스를 보면 다양한 카드 메뉴가 보이는 것을 알 수가 있다. 카드등록에 관한 설정을 하지 않은 사용자라면 위의 내용을 볼 수 없을 것이다. 위와 같은 경우는 우리카드, 하나카드, 신한카드, 국민카드의 네가지 카드가 보여지고 있다. 사용한 내용과 금액을 입력한 후에 '카드분류'의 항목을 클릭하면 현재 등록되어 있는 카드의 항목이 나오는데, 이중에서 자신이 사용한 카드를 선택하면 된다. 그리고 위에서는 금액을 입력할 때 현금부분에다가 금액을 입력했는데, 이것은 사용한 카드가 체크카드라서 사용한 금액이 바로 결제되서 현금과 비슷하게 사용되기 때문이다. 현금 다음 항목에 있는 '카드' 항목에 금액을 입력하면... 내역의 가장 아래에 있는 나간돈 합계에 포함이 되지는 않지만, 지출한 내역이 된다. 그렇기 때문에 카드항목은 금액을 입력하는데 있어서 약간의 주의를 요한다. 하지만, 이것에 대해 대비할 수 있는 방법이 있다. 오른쪽 위에 '항목추가' 버튼을 클릭하면 나타나는 메뉴중에서 현금흐름보기를 클릭하면 현재 내가 가지고 있는 자금이 어느정도 인지 상세내역에 포함되서 나온다. 카드 금액은 실제로 지출한 금액이 아니기 때문에 계산되어 나오지는 않지만, 현재 잔액과, 카드로 사용한 금액을 비교하여 사용할 수 있어서 편리하다.


카드항목 등록하기.
위의 그림1에서 카드로 분류하는 방법이 있다는 것을 알았다. 하지만, 이렇게 카드로 분류하기 위해서는 먼저 카드를 등록해야 한다. 카드를 등록하는 방법은 간단하다. 먼저 1번 네모박스에 있는 '카드대금' 을 클릭한다. 그러면 새로운 창이 나오는 것을 볼 수 있다.


그림2. 카드 관리 화면

처음 나오는 탭은 카드 관리이다. 위의 그림같은 경우는 이미 카드를 등록하였기 때문에 등록되어 있는 카드에 대한 설명이 나오게 된다. 카드를 등록하지 않은 사용자라면 아무런 내용이 없고, 등록을 하기 위한 폼만 나오게 될 것이다. 사용카드의 첫번째 항목은 카드를 서비스하는 회사를 선택하는 것이다. 회사를 선택하면 두번째 항목에서 자신이 사용하고 있는 카드의 종류를 선택할 수 있다. 거의 대부분의 카드가 등록되어 있기 때문에 없다고 불평하지 말고 잘 찾아보면 찾을 수 있을 것이다. 그리고 결제일과 별칭을 설정할 수 있는데, 결제일은 카드를 사용한 다음달의 결제일이 되면 그동안 계산되지 않았던 카드대금이 가계부에서 자동으로 계산되어 진다. 동일한 종류의 다양한 카드를 사용할 경우나, 카드에 특별한 이름을 붙여 쉽게 구분할 수 있다.


분류관리 탭.
분류관리하는 탭에서는 사용한 돈의 용도에 맞추어 항목을 구분해 줄 수 있다. 카테고리별로 나누어서 작성하는 것이 가능하기 때문에 사용자가 원하는데로 편하게 작성할 수 있다.


그림3. 분류관리 탭

하지만, 무작정 항목을 늘릴 수 있는것은 아니다. 대분류는 수입항목은 4개, 지출항목은 12가지로 정해져 있고, 소분류는 각 대분류별로 15개까지 사용자가 임의대로 추가, 삭제, 변경하여 사용할 수 있다. 자주쓰는 분류로 선택할 경우엔 항목분류메뉴에서 '자주쓰는 메뉴'라는 항목으로 바로 선택하는 것이 가능하게 된다. 그리고 네이버 가계부의 모든 설정을 변경하거나, 항목을 추가하고난 후에는 저장 버튼을 눌러서 저장을 해주어야 적용이 된다는 사실을 기억하자.


고정금액 관리
고정금액이라는 것은 정기적으로 적금을 하거나, 일정한 금액의 월급, 인터넷 요금등, 정해진 금액이 매달 반복적으로 입력이 이루어질 때, 미리 설정을 해두면 사용자가 입력하지 않아도 자동으로 입력이 되는 기능이다.


그림4. 고정금액 관리

보통 고정금액에는 저축, 보험, 적금, 인터넷 사용료, 관리비, 월급 등이 있는데, 이런 항목들을 '고정금액관리'로 설정해 두면 신경쓰지 않아도 자동으로 입력되어서 편리하다. 고정금액관리는 입력을 한 다음달부터 가계부에 적용이 되기 때문에, 당장 이번달은 직접 입력해 넣어야 한다.


태그로 관리하기.
분류항목과 카드로 지출이나 수입내역을 분류할 수 있게 되었다. 하지만, 이렇게 정형화 되어 있는 항목으로 분류하는데에는 한계가 있기 마련이다. 네이버 가계부에서는 좀더 유연한 분류가 가능하도록 태그 기능을 지원하고 있다. 이 태그 기능은 '희망목표'를 체크하는 기준이 되기도 한다.


그림5. 태그

가계부 화면의 가장 오른쪽 항목을 보면 '태그'로 분류되어 있는 것을 볼 수 있다. 이 칸에는 지출 내역에 대한 태그를 설정할 수가 있다. 사용자가 제주도 여행을 갔다 왔다고 하자. 그런데 사용자가 제주도 여행에 들어간 경비를 알고 싶어진다면 어떻게 구분을 지어야 할까? 분류 항목에 제주도 여행을 추가할 수도 없는 노릇이고... 이럴때 태그를 추가해 주면 같은 태그가 설정된 항목끼리의 지출 내역을 확인 할 수 있다. 태그는 사용자가 임의대로 입력이 가능하다. 그리고 여러개의 태그도 콤마로 구분하여 입력하는 것이 가능하다. 그렇기 때문에 목적에 따라 좀더 세분화된 재정 관리가 가능하게 된다.

Posted by seanhigher

댓글을 달아 주세요

  1. 2010.04.25 00:43 7579  댓글주소  수정/삭제  댓글쓰기

    가계부 써야겠다! :)

가계부를 작성하는것 뿐만 아니라 대부분의 할 것들에 목표를 가진다는 것은 그것을 지속하능하게 하는 원동력이 되곤 한다. 가계부라고 하는 금전을 관리하고, 우리의 삶 가운데 직접적으로 다가오는 부분에 있어서는 그 목적의 필요성이 더욱 절실한 것이다.




가계부의 목적
목표의 중요성은 아무리 강조를 해도 부족하지 않다. 네이버 가계부에서는 '희망 목표'라는 아이템을 통하여 가계부 작성하는 것을 계속하게끔 돕고 있다. 내가 가지고 있는 목표뿐만아니라, 나와 비슷한 처지에 있는 다른 사람의 희망목표를 보고 자신을 다시 돌아보고, 목표를 향해 노력할 수 있게 사용자에게 동기부여 하고 있다.


내가 가장 하고 싶은것은 무엇일까?
목표를 세우는데 있어서 가장 먼저 생각해야 할 것은 어떤 목표를 세우느냐이다. 잠시 눈을 감고 내가 가장 하고 싶은 것은 무엇인지 생각해 보길 바란다. 세계여행을 하는것, 자동차를 구입하는 것, 집을 장만하는 것, 유학을 가는 것 등등... 다양한 목표를 가질 수 있지만, 자신이 충분히 동기부여 할 수 있는 목적이어야 한다. 내가 가지고 있는 자산은 천만원에 불과하고, 월급은 150만원을 받고 있는 상황에서 '1년안에 10억을 만들기' 같은 목적은 전혀 실현 가능성이 없어 오히려 의욕을 떨어드릴 뿐이다. 가장 하고 싶고, 현실적인 목표가 필요하다.


나의 희망목표 세우기.
신중하게 고민을 한 후 자신이 가지고 있는 목적에 걸맞는 목표를 세웠다면, 네이버 가계부에서 '희망 목표'를 작성해 보도록 하자. 꿈으로만 그리던 목표에 한걸음 더 다가가는 계기가 될 것이다.

 
그림1. 네이버 가계부 화면

희망목표를 설정하고 진행상황을 파악하기 위해서는 먼저 해야 할 작업이 있는데, 태그를 입력하는 것이다. 목표를 세우고, 목표를 위해 돈을 사용했다면, 태그 부분에 목적에 걸맞는 '이름'을 지정해 주도록 한다. 위의 그림을 보면 '고정비용', '목돈마련' 등이 태그로 설정되어 있는 것을 볼 수가 있다. 태그는 콤마로 구분하여 여러개를 작성할 수 있다. 준비를 마쳤다면 희망목표를 세워기 위해 네이버 가계부 화면의 왼쪽 위를 보면 '희망목표/이야기' 라는 항목을 클릭하도록 한다.


그림2. 희망목표 페이지

아직 희망목표가 하나도 없다면 위와 같은 화면을 볼 수 있을 것이다. 오른쪽 아랫부분에 있는 '목표 만들기' 버튼을 클릭하자.


그림3. 희망목표 만들기

위와 같이 희망목표 만들기 화면이 나오게 되면, 차례대로 항목을 채워 내려가도록 한다. 저축을 하는 목적과, 목표금액을 설정하고, 기간을 선택한다. 선택한 기간내에서만 희망목표가 적용되기 때문에, 이미 목표를 두고 지출을 한 항목이 있다면 이전 기간까지 포함시키도록 해야 한다. 위에서도 말했듯이 희망목표를 구분짓는 것은 태그로 가능한데 새로운 태그를 입력하는 것이 아니라, 이미 선언된 태그만을 선택할 수 있도록 되어 있다. 그래서 희망목표를 설정하기 전에 태그를 입력하는 작업을 했던 것이다. '목돈마련'이라는 태그가 달려있는 금액에 대해서 목표에 맞다고 생각하면 '목돈마련'태그를 클릭한다. 그러면 위에 세로운 필드가 생기면서 태그가 입력되어진다. 기간내에 이 태그가 달려있는 금액을 모두 희망목표에 포함이 되는 것이다. 아래로 나의 다짐을 입력하고, 글공개를 '공개'로 설정하면 어느누구나가 가계부 내용을 볼 수 있게 된다.


그림4. 희망목표

간단하게 나만의 희망목표를 세웠다. 이제 이 목표를 이루기 위해 조금씩 저축하는 것을 게을리 하지 않는 것이 중요하다.

Posted by seanhigher

댓글을 달아 주세요

부자들의 공통점중 하나는 자산관리에 있어서 매우 철저하다는 것이다. 돈이 많아지면, 그만큼 관리에 소흘해질만도 한데, 그렇지 않다. 그렇다면 자산관리를 할 수 있는 방법은 무엇일까? 돈의 흐름을 잘 파악하고 절약하고, 모으는것이다. 그것을 가능하게 해주는 것이 가계부를 작성하는 것이다.




가계부의 진화.
가계 경제에 대한 중요성이 강조되면서 가계부를 쓰는 사람들이 많이 늘어났다. 하지만, 이전과 같이 노트를 이용하여 가계부를 작성하는 일은 매우 드물다. 조금 나아진 방법이 오피스의 대표 프로그램인 엑셀을 이용하는 것이다. 노트로 작성하는 가계부와 비슷하게 수입과 지출을 항목에 맞게 입력하면 현재 가지고 있는 금액이나, 지출, 수입이 항목별로 자동으로 계산이 가능해 진다. 가계부로써 할 수 있는 모든것이 가능하게 된다. 하지만, 한가지 결정적인 문제점은 엑셀의 함수를 잘 다뤄야 한다는 것이다. 정말 잘!


인터넷 가계부
지금과 같이 기술과 인터넷이 발달한 시대에서는 엑셀을 잘(?) 하지 못해도 편안하게 다양한 기능들을 사용할 수 있게끔 만들어주고 있다. 또한  어디서나 인터넷이 되는 환경이라면 사용할 수 있다는 것은 가계부를 정리하는데 있어서 잊지 않고 바로 기록할 수 있게끔 만들어 준다. 기록의 가장 중요한 요건중 하나는 즉시 기록할 수 있는 것이다.


네이버 가계부.
현제 인터넷에서 제공되고 있는 가계부는 다양하다. 네이버 가계부, 모네타 가계부, 유리트, 이지데이 가계부등이 있다. 각 서비스마다 특징적인 서비스가 있고, 그만큼 장단점이 드러나기 마련이다. 새로운 인터넷 서비스를 사용하면서 가장 먼저 생각하게 되는 것이 비용이 얼마나 들어가는가 이다. 거의 대부분의 인터넷 가계부가 무료로 제공되고 있다. 유리트 가계부만 평생 38500원이라는 가격에 서비스 되고 있다. 인터넷 가계부를 선택하는데 있어서 한가지 중요하게 생각해야 할것이 얼마나 보안이 철저한가이다. 가계의 경제상황을 한번에 알아 볼 수 있을 있기 때문에, 그리고 금융에 관련한 정보들이 포함되기 때문에 혹여나 하는 작은 보안의 문제가 크게 발전할 수 있다. 그런면에서 가장 인지도가 높은 네이버 가계부가 높은 점수를 받을만 하다. 하지만 보안성만 좋은것은 아니다. 실용적이고 성능만 좋다고 무식하게 생긴 제품을 선택하는 시대는 이미 지난지 오래다.


네이버 가계부 시작하기.
네이버 가게부를 시작하기 위해서 네이버 사이트를 둘러보았지만, 가계부 메뉴는 보이지 않는다. 그렇다고 검색을 해도 답은 나오지 않는다. 네이버 가계부는 검색, 뉴스, 까페, 블로그 등과 같이 자주 쓰이는 메뉴가 아니기 때문에 자주쓰는 메뉴에 비해 손이 더 움직여야 한다.


그림1. 네이버 가계부 메뉴 선택

네이버의 메인화면의 검색창 바로 아래를 보면 초록색의 띠가 있고, 자주사용되는 메뉴들이 나열되어 있는 것을 볼 수 있다. 한 가운데 정도에는 '더보기▼' 라는 메뉴를 클릭하면 위의 화면과 같이 다양한 네이버의 서비스를 볼 수 있다. 이 메뉴들은 가나다 순으로 정렬되어 있기 때문에 다른 메뉴를 찾고자 할때도 참고하면 좀더 쉽게 찾을 수 있을 것이다. 가나다 순으로 가계부는 가장 처음에 오는 메뉴이다. '가계부'를 클릭하면 가계부 메인 화면으로 이동할 수 있다.


그림2. 네이버 가계부 메인페이지.

가계부 메인 페이지로 이동했다고 해서 바로 가계부가 나오는것은 아니다. 가계부는 개인적인 정보를 포함하고 있기 때문에 당연히 로그인 과정이 포함되어야 한다. 로그인을 한 후에 오른쪽 아래부분을 보면 '네이버 가계부 시작하기' 라는 버튼을 볼 수가 있는데 이 버튼을 눌러서 시작을 해야 진짜 가계부 다운 화면이 나오게 된다.


그림3. 네이버 가계부 소개

만약 로그인을 하지 않은 상태에서 네이버 가계부를 시작하면 위와 같은 페이지를 보게 되는데, 한번쯤은 이 페이지에 들어가서 네이버 가계부의 사용법에 대해 알아보는 것도 나쁘진 않다. 제대로 로그인을 한 상태라면 다음과 같은 페이지를 볼 수 있을 것이다.


그림4. 가계부 화면

맨 처음 가계부를 시작하게 되면 모든 항목의 금액은 0으로 설정되어 있고, 사용내역도 없다. 아직 아무것도 입력하지 않은 상태이기 때문에 당연한 이야기이다. 네이버 가계부를 시작하면서 주의해야 할 점은 한 계정당 하나의 가계부 밖에 만들지 못한다는 것이다. 따로따로 가계부를 두어 재정을 관리하고 싶은 사람도 있겠지만, 네이버에서는 그러한 기능을 없애는 대신, 하나의 가계부 안에서 여러개의 가계부를 작성하는 것과 같은 효과를 주도록 노력했다. 가계부의 화면은 크게 세부분으로 나뉠 수 있다. 첫번째 부분은 전체적인 예산 계획에 대한 메뉴가 들어간다. 목적을 가지고 가계부를 작성한다면 더욱 더 지속성있게 가계부를 작성할 수 있을 것이다. 두번째 부분은 현재의 자금상황을 보여준다. 현재 내가 가지고 있는 돈은 얼마인지 예산에 맞추어 쓰고 있는지, 저축의 비율은 어느정도인지 보여준다. 세번째 부분은 지출, 수입의 실제적인 목록이 나타난다. 날짜별로 지출 수입의 내역을 자세하게 볼 수 있고, 기간을 변경하면 기간동안의 내역으로 변경된다. 기본적으로는 '나간돈' 이 기본으로 설정되어 있다. 일반적인 가계에서는 들어온 돈의 항목보다는 나간돈의 항목이 많을 수 밖에 없기 때문이다. 날짜와 사용내역, 금액등을 입력하고 '저장하기'버튼을 누르면 아래부분의 사용내역과 왼쪽의 항목들이 자동으로 계산되어 나온다.


그림5. 월별로 보기

지출 수입 내역은 지출별로, 수입별로 탭이 나뉘어져 있어서 분리된 화면만 볼 수 있지만, '달력'을 선택하면 한달동안의 지출 수입 내역을 한번에 볼 수 있다.

네이버 가계부를 사용하는 것은 그리 어렵지 않기 때문에 몇번 사용을 해보면 쉽게 적응할 수 있을 것이다. 이제부터 네이버 가계부로 부자되는 습관을 만들어 보자!

Posted by seanhigher

댓글을 달아 주세요

분할 컨트롤은 두세가지의 항목을 버튼의 형식으로 한번에 표현할 수 있다. 다양한 기능을 작은 화면안에 넣기 위해 매우 효율적인 방법이라고 할 수 있다.



Segmented Control - Displays an element that comprises multiple segments, each of which functions as a discrete button. Each segment can display either text or an image, but not both. UISegmentedControl ensures that the width of each segment is proportional, based on the total number of segments, unless you set a specific width.

분할컨트롤의 항목

▼ Segmented Control
Style : 분할 컨트롤 버튼의 스타일을 선택할 수 있다. Plain, Bordered, Bar 의 세가지 스타일이 미지 정의되어 있다.
Segments : 버튼의 분할 수를 나타낸다.
Tint : 분할컨트롤의 스타일을 Bar 형식으로 할 경우 색상을 변경할 수 있다.
Segment 0 ~ : 각각의 분할 영역에 대한 속성을 설정할 수 있다.
Title : 버튼에 표시되는 텍스트를 나타낸다.
Image : 이미지로 표현이 가능하다.
Content : 내용이 표시되는 위치를 설정한다. Selected 항목에 체크가 되어 있으면 처음 화면에서 기본으로 선택되어 있다.

▼ Control
Content : 각 오브젝트들의 정렬방식을 정할 수 있다. 그림을 보면 이해할 수 있으므로 보고 알맞은 것으로 정렬을 하면 된다. Highlighted, Selected, Enabled 의 추가적인 선택 사항들이 있다. 어떤 오브젝트들을 선택하고, 정렬에 포함할 것인지에 대해 결정하게 된다.

▼ View
Mode : 뷰에서 상속을 받아 갖고 있는 속성이기 때문에 이미지 뷰의 속성의 특징을 갖지만, 텍스트에서는 크게 영향을 주지 않는다.
Alpha : 이미지의 투명도를 조절하여 뒤에 있는 화면이 보이도록 한다. 숫자가 1 이하일 경우 투명도를 위한 연산을 해야 하기 때문에 필요할 때 이외에는 사용을 자제하도록 한다.
Background : 텍스트 배경 영역의 배경색을 지정한다. 특별한 이유가 없다면 투명상태로 유지한다.
Tag : 개발자가 각 컨트롤러를 구분하기 위해 임의의 태그를 줄 수 있다. 이 항목에 있어서는 IB 나 Xcode 등 애플리케이션이 임의로 변경할 수 없기 때문에 절대적인 구분이 가능하다.
Drawing : opaque 체크박스는 불투명 상태를 설정하게 된다. 알파값과의 차이점은 텍스트가 아닌 뷰에 직접 적용된다는 것이다. Hidden 체크박스는 컨트롤를 숨기는 역할을 한다. Clear Context Before Drawing 체크박스는 실제 컨트롤을 그릴 영역을 깨끗히 지운 후에 새로운 뷰를 그리게 한다. Clip Subviews 체크박스는 하위뷰가 있을 경우 어떻게 표현하지에 대해 설정한다. 체크할 경우 보여지지 않는 부분을 삭제 한 후에 이미지를 보여주게 되는데, 이것은 아이폰 OS 의 입장에서 삭제를 하지 않고 보여주는 것보다 더 자원을 소모하는 것이기 때문에 체크를 하지 않는 것이 기본 설정이다. Autoresize Subviews 체크박스는 뷰의 크기가 변경될 경우 포함되어 있는 하위 뷰의 크기도 변경되도록 한다.
Stretching : 표현하고자 하는 영역이 뷰보다 작을 경우 어떻게 확대할 것인지에 대한 설정을 할 수 있다. 이역시 텍스트에서는 크게 작용하지 않는다.
Interaction : User Interaction Enabled 는 사용자가 객체와 어떤 액션을 할 수 있도록 허용해준다. 이미지와 라벨의 경우는 대게 일반적인 정보만을 보여주기 대문에 이 옵션을 해제해 놓는다. 하지만, 버튼과 같이 액션이 필요할 경우엔 체크를 해 주어야 한다. Multiple Touch 멀티터치 이벤트를 허용할 것인가 이다. 멀티터치를 사용하지 않는다면 해제해 놓도록 한다.
Posted by seanhigher

댓글을 달아 주세요

모바일 환경이라함은 한정된 공간적 제약을 가지고 있다. 그렇기 때문에 컨트롤러 하나하나를 배치하거나, 레이아웃을 작성하는데 있어서 신중을 기해야 한다. 분할 컨트롤은 이러한 공간적 제약을 조금이나마 벗어날 수 있는 기능을 제공해 준다. 백개의 버튼을 한 화면에 담을 수는 없지만, 열개씩 나누어서 볼 수 있다면 충분히 넉넉하게 볼 수가 있다.


New project.
새로운 프로젝트를 시작한다. 'View-based Application' 을 선택하고 프로젝트 이름은 'roomControl' 로 하였다. 이번에 만들게 될 애플리케이션은 방의 불을 On/Off 하는기능, 온도를 조절하는 기능, 스텝을 호출하는 기능을 분할컨트롤 버튼을 이용하여 선택적으로 보여지게 한다. 우선은 프로그램에 대한 구상을 한다.


그림1. 프로젝트 구상

애플리케이션을 구상하는데 있어서 가장 먼저 해야 할 것은 아웃렛과 액션을 선언해야 하는 부분은 어떤 부분인가이다. 이 프로젝트에서는 분할 컨트롤을 선택하여 모든 객체에 hidden 메소드를 이용해야 하기때문에 표현되는 모든 라벨, 버튼, 스위치, 슬라이더 객체가 아웃렛으로 선언되어야 한다. 또한 액션으로는 어떠한 액션이 정의되어야 하는지 계획해야 한다.


첫번째 segmented Control
모든 화면을 한꺼번에 설명하기엔 양이 조금 많을 수 있기 때문에 한 화면씩 구체화 하도록 한다. 분할 컨트롤은 슬라이더와 마찬가지로 이미 아웃렛이 선언되어 있기 때문에 임의로 선언할 필요는 없다. 하지만, 분할 컨트롤의 선택에 대한 액션은 구현해 주어야 한다. 액션을 구현해 주지 않으면 분할컨트롤 객체가 무엇을 해야 할찌 모르기 때문이다. 첫 분할컨트롤은 방의 불을 조절하는 스위치와 라벨이 자리하고 있다. 세개의 스위치와 세개의 라벨이 모두 아웃렛으로 선언되어야 한다. 그리고 스위치는 On/Off 를 표시할 수 있도록 액션이 선언되어야 한다. 분할컨트롤와 첫번재 컨트롤에 들어가는 아웃렛은 다음과 같이 선언할 수 있다.

<roomControlViewController.h>
@interface roomControlViewController : UIViewController {
    UISwitch *roomLight1_Switch;
    UISwitch *roomLight2_Switch;
    UISwitch *indoorLight_Switch;
    UILabel *roomLight1_Label;
    UILabel *roomLight2_Label;
    UILabel *indoorLight_Label;
}

@property (nonatomic, retain) IBOutlet UISwitch *roomLight1_Switch;
@property (nonatomic, retain) IBOutlet UISwitch *roomLight2_Switch;
@property (nonatomic, retain) IBOutlet UISwitch *indoorLight_Switch;
@property (nonatomic, retain) IBOutlet UILabel *roomLight1_Label;
@property (nonatomic, retain) IBOutlet UILabel *roomLight2_Label;
@property (nonatomic, retain) IBOutlet UILabel *indoorLight_Label;

- (IBAction) toggleControls: (id) sender;
- (IBAction) switchChange: (id)sender;


<roomControlViewController.m>
@implementation roomControlViewController

@synthesize roomLight1_Switch;
@synthesize roomLight2_Switch;
@synthesize indoorLight_Switch;
@synthesize roomLight1_Label;
@synthesize roomLight2_Label;
@synthesize indoorLight_Label;

- (IBAction) toggleControls: (id)sender {
    if([sender selectedSegmentIndex] == 0) {
        roomLight1_Switch.hidden = NO;
        roomLight2_Switch.hidden = NO;
        indoorLight_Switch.hidden = NO;
        roomLight1_Label.hidden = NO;
        roomLight2_Label.hidden = NO;
        indoorLight_Label.hidden = NO;
    } else if([sender selectedSegmentIndex] == 1) {
        roomLight1_Switch.hidden = YES;
        roomLight2_Switch.hidden = YES;
        indoorLight_Switch.hidden = YES;
        roomLight1_Label.hidden = YES;
        roomLight2_Label.hidden = YES;
        indoorLight_Label.hidden = YES;
    } else if([sender selectedSegmentIndex] == 2) {
        roomLight1_Switch.hidden = YES;
        roomLight2_Switch.hidden = YES;
        indoorLight_Switch.hidden = YES;
        roomLight1_Label.hidden = YES;
        roomLight2_Label.hidden = YES;
        indoorLight_Label.hidden = YES;
    }
}

- (IBAction) switchChange: (id)sender {
    UISwitch *whichSwitch = (UISwitch *)sender;
    BOOL setting = whichSwitch.isOn;
    [roomLight1_Switch setOn:setting animated:YES];
    [roomLight2_Switch setOn:setting animated:YES];
    [indoorLight_Switch setOn:setting animated:YES];
}

... ... ...

- (void)dealloc {
    [roomLight1_Switch release];
    [roomLight2_Switch release];
    [indoorLight_Switch release];
    [super dealloc];
}


위 소스코드에서 toggleControls 액션은 분할컨트롤에 대한 액션이다. 액션 개체는 sender 라는 인자를 통해 값을 전달받을 수 있는데, 분할컨트롤은 선택영역에 따라 인덱스값을 받을 수 있다. 분할컨트롤의 분할컨트롤의 첫번째는 '0', 두번째는 '1', 세번째는 '2' 와 숫자의 배열 형식을 갖는다. 이 값은 'selectedSgmentedIndex' 라는 변수값으로 구분지을 수 있다. 이 값을 비교함으로써 분할컨트롤이 어떤 값을 선택하였는지 알 수 있게 된다. 분할컨트롤이 선택되고 '{ }' 안의 내용을 보면 hidden 이라는 메소드가 호출되는 것을 볼 수 있다. UIview 를 상속받는 모든 객체의 기본적인 메소드이며, 화면에 표시할것인지를 결정하는 요소가 된다. 'NO' 일경우는 숨기지 않겠다는 뜻으로 화면에 표시가 되고, 'YES' 값일 경우는 숨기겠다는 뜻으로 화면에 표시하지 않겠다는 뜻이 된다. switchChange 액션은 스위치가 On / Off 되는 액션을 표현한다. 중간에 setting animated 옵션은 스위치가 순식간에 변하게, 또는 애니메니션이 적용되어 변하게 되는지 설정할 수 있다.


첫번째 레이아웃 작성.
레이아웃을 작성하기 위해서는 인터페이스 빌더를 실행해야 한다. 'Resources' 폴더의 'roomControlViewController.xib' 파일을 더블클릭하여 인터페이스 빌더를 실행한다. 분할 컨트롤러를 이용한 첫번째 화면의 레이아웃을 작성한다. 라이브러리 윈도우에서 분할 컨트롤 객체, 스위치 객체를 드래그하여 뷰 윈도우의 적당한 위치에 배치시킨다. 그리고 라벨을 위치시키고 텍스트 내용을 변경한다.


그림2. 첫번째 레이아웃 작성

분할 컨트롤러는 기본적으로 두개의 선택 버튼을 기본으로 제공한다. 하지만, 위의 그림처럼 세개의 메뉴로 늘리기 위해서는 Attibute 윈도우의 segments 항목을 '2' 에서 '3'으로 늘려주면 항목수가 하나 늘어나게 된다.


액션과 아웃렛 연결하기.
액션과 아웃렛은 인터페이스 빌더를 통해 연결하지 않으면 아무 소용이 없다. 아웃렛을 연결하는 방법에는 두가지가 있다. 첫번째는 'ctrl' 키를 누른채로 main 윈도우의 File's Owner 아이콘을 클릭하고, 아웃렛을 연결하고자 하는 객체로 드래그하여 선택하는것이다. 두번째는 File's Owner 아이콘을 선택한 후 Connections 윈도우에서 아웃렛을 먼저 선택하여 원하는 객체에 연결 시키는 방법이다. 방법의 차이만 있을 뿐 다른 차이점은 없기 때문에 선호하거나, 편한 방법으로 세개의 스위치와, 라벨의 아웃렛을 연결한다. 액션을 연결하는 방법도 아웃렛을 연결하는 것과 비슷한 방식으로 이루어진다. 액션을 연결하는 방법 역시 두가지가 있다. 첫번째는 아웃렛을 연결하는 방법과 반대의 순서로 하면 된다. 'ctrl' 키를 누르는 것은 동일하고, File's Owner 에서 객체로 드래그 하는 것이 아니라, 객체를 먼저 선택한 후 File's Owner 아이콘으로 드래그하는 것이다. 그러면 Events 항목이 팝업으로 나오게 되고, 적절한 항목을 선택하면 된다.


그림3. 액션 연결하기

액션을 연결하는 두번째 방법은 File's Owner 아이콘을 선택한 후 Connections 윈도우를 이용하는 것이다. 아웃렛을 연결하는 것과 마찬가지로 Connections 윈도우를 보면 아랫부분에 Received Actions 항목에 이미 선언한 액션들을 볼 수가 있다. 원하는 액션의 항목 오른쪽으로 마우스 커서를 가져가면 원안에 십자가 모양이 생기게 된다. 이것을 액션을 연결하고자 하는 객체에 끌어다가 놓으면 팝업으로 액션 항목이 나오는데, 가장 적절한 액션을 선택하도록 한다. 스위치와 분할 컨트롤러에는 Value Changed 값이 가장 적당하다. togleControls 액션도 분할컨트롤러에 연결하도록 한다. 첫번째로 작성한 컨트롤러가 잘 작동하는지 시뮬레이션을 해보도록 한다. 분할컨트롤의 첫번째 버튼에만 화면이 나오는 것을 볼 수 있을 것이다. 만약 오류가 있어가, 생각했던대로 실행이 되지 않는다면 오류를 확인해 보고, 위에서부터 차근차근 다시 해보길 바란다.


그림4. 첫번째 분할컨트롤 작성 후 시뮬레이션 화면


두번째 Segmented Control
두번째 분할컨트롤 화면은 위와 같은 순서를 반복하면 된다. 두번째 화면에서는 슬라이더에 의한 제어를 하기 때문에 세개의 슬라이더와 세개의 라벨이 필요하다. 다음과 같이 코드를 입력한다.

<roomControlViewController.h>
@interface roomControlViewController : UIViewController {
    ... ...

    UILabel *roomTmep1_SliderLabel;
    UILabel *roomTemp2_SliderLabel;
    UILabel *indoorTemp_SliderLabel;
    UISlider *roomTemp1_Slider;
    UISlider *roomTemp2_Slider;
    UISlider *indoorTemp_Slider;

}
... ...

@property (nonatomic, retain) IBOutlet UILabel *roomTmep1_SliderLabel;
@property (nonatomic, retain) IBOutlet UILabel *roomTemp2_SliderLabel;
@property (nonatomic, retain) IBOutlet UILabel *indoorTemp_SliderLabel;
@property (nonatomic, retain) IBOutlet UISlider *roomTemp1_Slider;
@property (nonatomic, retain) IBOutlet UISlider *roomTemp2_Slider;
@property (nonatomic, retain) IBOutlet UISlider *indoorTemp_Slider;

... ...

- (IBAction) SliderChangeRoom1: (id)sender;
- (IBAction) SliderChangeRoom2: (id)sender;
- (IBAction) SliderChangeIndoor: (id)sender;


<roomControlViewController.m>
... ...
@synthesize roomTmep1_SliderLabel;
@synthesize roomTemp2_SliderLabel;
@synthesize indoorTemp_SliderLabel;
@synthesize roomTemp1_Slider;
@synthesize roomTemp2_Slider;
@synthesize indoorTemp_Slider;
... ...

- (IBAction) toggleControls: (id)sender {
    if([sender selectedSegmentIndex] == 0) {
        ... ...

        roomTmep1_SliderLabel.hidden = YES;
        roomTemp2_SliderLabel.hidden = YES;
        indoorTemp_SliderLabel.hidden = YES;
        roomTemp1_Slider.hidden = YES;
        roomTemp2_Slider.hidden = YES;
        indoorTemp_Slider.hidden = YES;
    } else if([sender selectedSegmentIndex] == 1) {
        ... ...

        roomTmep1_SliderLabel.hidden = NO;
        roomTemp2_SliderLabel.hidden = NO;
        indoorTemp_SliderLabel.hidden = NO;
        roomTemp1_Slider.hidden = NO;
        roomTemp2_Slider.hidden = NO;
        indoorTemp_Slider.hidden = NO;
    } else if([sender selectedSegmentIndex] == 2) {
        ... ...

        roomTmep1_SliderLabel.hidden = YES;
        roomTemp2_SliderLabel.hidden = YES;
        indoorTemp_SliderLabel.hidden = YES;
        roomTemp1_Slider.hidden = YES;
        roomTemp2_Slider.hidden = YES;
        indoorTemp_Slider.hidden = YES;
    }
}
... ...

- (IBAction) SliderChangeRoom1: (id)sender {
    UISlider *slider = (UISlider *)sender;
    int progressAsInt = (int)(slider.value + 0.5f);
    NSString *newText = [[NSString alloc] initWithFormat: @"Room1 temperature is %d degrees", progressAsInt];
    roomTmep1_SliderLabel.text = newText;
    [newText release];
}

- (IBAction) SliderChangeRoom2: (id)sender {
    UISlider *slider = (UISlider *)sender;
    int progressAsInt = (int)(slider.value + 0.5f);
    NSString *newText = [[NSString alloc] initWithFormat: @"Room2 temperature is %d degrees", progressAsInt];
    roomTemp2_SliderLabel.text = newText;
    [newText release];
}

- (IBAction) SliderChangeIndoor: (id)sender {
    UISlider *slider = (UISlider *)sender;
    int progressAsInt = (int)(slider.value + 0.5f);
    NSString *newText = [[NSString alloc] initWithFormat: @"Indoor temperature is %d degrees", progressAsInt];
    indoorTemp_SliderLabel.text = newText;
    [newText release];
}
... ...

- (void)dealloc {
    ... ...

    [roomTmep1_SliderLabel release];
    [roomTemp2_SliderLabel release];
    [indoorTemp_SliderLabel release];
    [roomTemp1_Slider release];
    [roomTemp2_Slider releasd];
    [indoorTemp_Slider release];
    [super dealloc];
}

첫번째 화면을 작성하면서 작성했던 소스코드에 위의 내용을 추가하면 된다. 슬라이더의 경우 일반적으로 아웃렛을 선언하지 않아도 그 값을 받아 사용할 수 있지만, 이번 프로젝트에서는 분할컨트롤러를 이용할때 hidden 옵션을 사용해야 하기 때문에 아웃렛을 선언하여 hidden 옵션을 사용할 수 있도록 하였다. 화면의 작업을 마친 후에는 분할컨트롤의 항목도 신경을 써 주어야 한다. 어느 버튼을 선택했을때 보여야 할찌 각 객체별로 모두 선언을 해 주어야 한다. 각 슬라이더의 액션은 슬라이더의 인자값을 받아서 라벨에 출력하는 액션이다. 먼저 슬라이더의 인자값을 구하고, 정수형으로 변환한 후 텍스트 형식으로 바꾸어 준다. 그리고 아웃렛으로 선언된 라벨에 출력해준다. 코딩을 하면서 retain 으로 선언된 모든 객체들은 꼭 release를 해서 자원의 낭비를 막아야 한다는 것을 잊지 말기 바란다.


화면디자인하고, 아웃렛과 액션 연결하기.
다시 인터페이스 빌더로 이동하여 화면을 디자인하도록 한다. 분할 컨트롤을 사용하는 경우 이미 객체들이 배치되어 있는 상태에서 그 위에 또 다른 객체를 표현하는 것이기 때문에 화면 하나씩 순서대로 작성하는 것이 화면을 구성하는데 불편함을 덜 수 있다.


그림5. 화면디자인및 아웃렛, 액션 연결

첫번째 페이지를 만들때와 동일한 방법으로 뷰 윈도우의 객체들과 아웃렛을 이어주고, 액션을 연결해 주면 된다. 한가지 주의해야 할 점은 두번째 화면의 객체들은 Attribute 윈도우에서 View -> Drawing -> Hidden 을 체크해 주어야 한다. 그렇지 않으면 처음 화면에서 위의 화면과 같이 겹치는 화면을 보게 될 것이다.


세번째 Segmented Control
세번째는 버튼을 이용한 화면이다. 버튼을 이용한 액션을 가장 기초적인 액션이기 때문에 어렵지 않게 구현할 수 있어야 한다. 잘 모르겠다면 이전의 포스팅을 보면서 버튼을 구현하도록 한다. 이 프로젝트에 필요한 버튼은 여섯개이다. 버튼의 내용을 표현하기 위한 하나의 라벨이 필요하다. 또 버튼의 내용을 인자값으로 전달받아서 출력하기 위한 액션을 추가한다.

<roomControlViewController.h>
@interface roomControlViewController : UIViewController {
    ... ...

    UIButton *roomStaff1_Button;
    UIButton *roomStaff2_Button;
    UIButton *roomStaff3_Button;
    UIButton *roomStaff4_Button;
    UIButton *roomStaff5_Button;
    UIButton *roomStaffAll_Button;
    UILabel *callStaff;

}
... ...

@property (nonatomic, retain) IBOutlet UIButton *roomStaff1_Button;
@property (nonatomic, retain) IBOutlet UIButton *roomStaff2_Button;
@property (nonatomic, retain) IBOutlet UIButton *roomStaff3_Button;
@property (nonatomic, retain) IBOutlet UIButton *roomStaff4_Button;
@property (nonatomic, retain) IBOutlet UIButton *roomStaff5_Button;
@property (nonatomic, retain) IBOutlet UIButton *roomStaffAll_Button;
@property (nonatomic, retain) IBOutlet UILabel *callStaff;

... ...

- (IBAction) buttonPress: (id)sender;


<roomControlViewController.m>
... ...
@synthesize roomStaff1_Button;
@synthesize roomStaff2_Button;
@synthesize roomStaff3_Button;
@synthesize roomStaff4_Button;
@synthesize roomStaff5_Button;
@synthesize roomStaffAll_Button;
@synthesize callStaff;

... ...

- (IBAction) toggleControls: (id)sender {
    if([sender selectedSegmentIndex] == 0) {
        ... ...

        roomStaff1_Button.hidden = YES;
        roomStaff2_Button.hidden = YES;
        roomStaff3_Button.hidden = YES;
        roomStaff4_Button.hidden = YES;
        roomStaff5_Button.hidden = YES;
        roomStaffAll_Button.hidden = YES;
        callStaff.hidden = YES;

    } else if([sender selectedSegmentIndex] == 1) {
        ... ...

        roomStaff1_Button.hidden = YES;
        roomStaff2_Button.hidden = YES;
        roomStaff3_Button.hidden = YES;
        roomStaff4_Button.hidden = YES;
        roomStaff5_Button.hidden = YES;
        roomStaffAll_Button.hidden = YES;
        callStaff.hidden = YES;

    } else if([sender selectedSegmentIndex] == 2) {
        ... ...

        roomStaff1_Button.hidden = NO;
        roomStaff2_Button.hidden = NO;
        roomStaff3_Button.hidden = NO;
        roomStaff4_Button.hidden = NO;
        roomStaff5_Button.hidden = NO;
        roomStaffAll_Button.hidden = NO;
        callStaff.hidden = NO;

    }
}
... ...

- (IBAction) buttonPress: (id)sender {
    NSString *title = [sender titleForState:UIControlStateNormal];
    NSString *newText = [[NSString alloc] initWithFormat: @"%@ called", title];
    callStaff.text = newText;
    [newText release];
}

... ...

- (void)dealloc {
    ... ...

    [roomStaff1_Button release];
    [roomStaff2_Button release];
    [roomStaff3_Button release];
    [roomStaff4_Button release];
    [roomStaff5_Button release];
    [roomStaffAll_Button release];
    [callStaff release];

    [super dealloc];
}

위에서 분할 컨트롤과, 스위치, 슬라이더에 대한 액션을 구현했다면 나머지 버튼을 구현하는 것은 크게 어렵지 않다. 위 소스 코드를 참조하여 코딩을 하도록 한다. buttonPress 액션은 각 버튼에 대한 값들을 받아와서 새로운 문자열을 만들고, 선언된 라벨에 출력하는 액션이다. 분할컨트롤에 항목을 추가하는 것과, 객체들을 release 하는것도 빠뜨리지 않고 하도록 한다. 모든 프로그래밍을 마친 후에는 인터페이스 빌더로 이동하여 인터페이스 디자인을 한다.


그림6. 세번째 분할컨트롤 화면 구현

이전의 인터페이스들이 그대로 보여지기 때문에 화면에 매우 복잡해지기 시작한다. 하나하나 잘 체크해가며 객체들을 배치하도록 한다. 객체를 배치한 후에는 아웃렛을 연결하고, 액션들을 연결하도록 한다. 어렵지 않게 마지막 화면을 마무리 할 수 있을 것이다.


그림7. 완성된 애플리케이션 시뮬레이션

위와 같이 분할컨트롤로 애플리케이션을 제작하면 더 많은 정보들을 좀더 효율적으로 보여줄 수 있다.

Posted by seanhigher

댓글을 달아 주세요

최근에 달린 댓글

글 보관함