본문 바로가기

OS X Programming

OS X Dev - Label과 Button의 기초

OS X 프로그래밍에서 어쩌면 가장 많이 사용되는 컨트롤인 레이블과 버튼의 기초적인 사용법, 버튼에 액션을 구현하고 그에 따라 레이블에 텍스트를 지정하고 위치를 이동하는 등의 아주 기초적인 내용에 대해 알아보겠습니다.


예제 소스 프로젝트 준비를 위해 MainWindowController가 메인 UI가 되는 프로젝트를 생성합니다.

특별한 언급이 없는 한, 앞으로 진행되는 모든 예제 소스의 프로젝트는 아래의 준비 작업을 거치도록 합니다.


[ 기본 프로젝트 생성 ]

  1. Xcode에서 OS X Cocoa Application 프로젝트를 생성합니다.
  2. MainMenu.xib에서 Window를 제거합니다.
  3. File -> New -> File..을 선택하여 OS X의 Objective-C Class를 선택, NSWindowController를 부모로 지정하고 MainWindowController라는 이름으로 클래스를 하나 생성합니다. 이 때 With XIB for user interface를 체크 선택합니다.
  4. AppDelegate.m에서 MainWindowController.h를 import하고 applicationDidFinishLaunching 메서드에 아래처럼 코드를 추가합니다.

 #import "AppDelegate.h"

#import "MainWindowController.h"


@implementation AppDelegate


- (void)dealloc

{

    [super dealloc];

}


- (void)applicationDidFinishLaunching:(NSNotification *)aNotification

{

MainWindowController *mwc = [[MainWindowController alloc] initWithWindowNibName:@"MainWindowController"];

[mwc.window makeKeyWindow];

}


@end


 

기본 프로젝트가 준비되었으면 아래 그림처럼 MainWindowController.xib의 윈도우에 Label 하나와 Button 5개를 올려 놓습니다. Label은 attribute inspector에서 중앙정렬로 지정합니다.


그리고 레이블에 대해서는 testLabel이라는 이름으로 아웃렛 변수를 연결하고 각 버튼들에 대해서는 gpLeftTop, goRightTop, goLeftBottom, goRightBottom, goCenter라는 이름으로 각각 액션 메서드를 연결합니다. 각 컨트롤의 텍스트는 더블클릭으로 입력할 수 있습니다. 아웃렛 변수는 New Referencing Outlet으로 액션 메서드는 selector로 연결하면 됩니다.



혹은 Xcode의 Assistant Editor기능을 통해 해당 UI 컨트롤을 선택하고 control + 드래그드롭으로 코드 자동추가와 동시에 연결할 수도 있습니다.


그리고 마지막으로 xib의 Window 바로 하위에 있는 View에 대해 baseView라는 이름으로 역시 아웃렛 변수를 연결합니다.


위 과정으로 아웃렛 변수와 액션 메서드가 연결된 코드의 헤더는 아래와 같습니다.


 @interface MainWindowController : NSWindowController

{

IBOutlet NSView *baseView;

IBOutlet NSTextField *testLabel;

}


- (IBAction)goCenter:(id)sender;

- (IBAction)goLeftTop:(id)sender;

- (IBAction)goRightTop:(id)sender;

- (IBAction)goLeftBottom:(id)sender;

- (IBAction)goRightBottom:(id)sender;


각 액션 메서드에 대한 구현은 아래와 같습니다.


 - (void)windowDidLoad

{

    [super windowDidLoad];

    

[self goCenter:nil];

}


- (IBAction)goCenter:(id)sender

{

testLabel.stringValue = @"중앙";

testLabel.alignment = NSCenterTextAlignment;

CGRect rect = testLabel.frame;

rect.origin.x = (baseView.frame.size.width - rect.size.width) / 2;

rect.origin.y = (baseView.frame.size.height - rect.size.height) / 2;

testLabel.frame = rect;

}


- (IBAction)goLeftTop:(id)sender

{

testLabel.stringValue = @"좌측 상단";

testLabel.alignment = NSLeftTextAlignment;

CGRect rect = testLabel.frame;

rect.origin.x = 0;

rect.origin.y = baseView.frame.size.height - rect.size.height;

testLabel.frame = rect;

}


- (IBAction)goRightTop:(id)sender

{

testLabel.stringValue = @"우측 상단";

testLabel.alignment = NSRightTextAlignment;

CGRect rect = testLabel.frame;

rect.origin.x = baseView.frame.size.width - rect.size.width;

rect.origin.y = baseView.frame.size.height - rect.size.height;

testLabel.frame = rect;

}


- (IBAction)goLeftBottom:(id)sender

{

testLabel.stringValue = @"좌측 하단";

testLabel.alignment = NSLeftTextAlignment;


CGRect rect = testLabel.frame;

rect.origin.x = 0;

rect.origin.y = 0;

testLabel.frame = rect;

}


- (IBAction)goRightBottom:(id)sender

{

testLabel.stringValue = @"우측 하단";

testLabel.alignment = NSRightTextAlignment;


CGRect rect = testLabel.frame;

rect.origin.x = baseView.frame.size.width - rect.size.width;

rect.origin.y = 0;

testLabel.frame = rect;

}


windowDidLoad 에서 goCenter가 바로 실행되도록 하였습니다.


위 메서드 중 goLeftTop 메서드만 한 번 자세히 살펴보겠습니다.


  testLabel.stringValue = @"좌측 상단";

testLabel.alignment = NSLeftTextAlignment;


레이블에 "좌측 상단"이라는 타이틀을 지정하고 왼쪽 정렬을 하라는 의미입니다.

stringValue 프로퍼티는 NSControl의 프로퍼티로 코코아의 거의 모든 컨트롤들이 NSControl을 계승하므로 이 프로퍼티를 사용할 수 있습니다. (iOS에서의 title이나 text와 같은 프로퍼티는 없습니다.) intValue, doubleValue등을 이용해 문자열뿐만 아니라 정수나 실수형으로 바로 가지고 오거나 지정할 수도 있습니다.


  CGRect rect = testLabel.frame;

rect.origin.x = 0;

rect.origin.y = baseView.frame.size.height - rect.size.height;

testLabel.frame = rect;


이 코드를 자세히 보니 좀 이상합니다. 좌측 상단으로 이동시키는 코드인데 y값이 0이 아닙니다. 그것은 OS X에서는 iOS와는 달리 윈도우의 좌측 하단이 기준점 (0, 0)이기 때문에 그렇습니다.




일단 여기까지 하고 빌드를 통해 어플을 실행해 보시기 바랍니다. 그리고 각 버튼을 눌러 보시기 바랍니다. 이상합니다. 버튼을 아무리 눌러도 레이블 택스트만 변경될 뿐 위치 이동이 되지 않습니다. 바로 Auto Layout 때문에 그렇습니다. 오토레이아웃에 대해서는 다음 기회에 다루기로 하고 해당 기능은 끄겠습니다. xib에서 끌 수 있습니다.




다시 실행해보시면 잘 동작이 됨을 확인 할 수 있습니다.


그런데 무언가 개운치 않습니다. iOS도 그렇지만 OS X에서도 애니메이션이 들어가지 않으면 좀 답답한 느낌이지요?

애니메이션과 가장자리 여백을 좀 적용하고 중복코드를 제거해 보도록 하겠습니다.


아래는 완성된 코드입니다.


 //

//  MainWindowController.m

//  01 BasicLabelButton

//

//  Created by Joon on 12. 8. 30..

//  Copyright (c) 2012 Joon. All rights reserved.

//


#import "MainWindowController.h"


#define kLabelMargineInView 10



@interface MainWindowController ()


@end


@implementation MainWindowController


- (id)initWithWindow:(NSWindow *)window

{

    self = [super initWithWindow:window];

    if (self) {

        // Initialization code here.

    }

    

    return self;

}


- (void)windowDidLoad

{

    [super windowDidLoad];

    

[self goCenter:nil];

}


- (void)moveLabelTo:(CGPoint)position

  withTitle:(NSString *)title

  withAlignment:(NSTextAlignment)alignment

{

testLabel.stringValue = title;

testLabel.alignment = alignment;

CGRect rect = testLabel.frame;

rect.origin = position;

[testLabel.animator setFrame:rect];

}


- (IBAction)goCenter:(id)sender

{

CGRect rect = testLabel.frame;

CGPoint position = CGPointMake((baseView.frame.size.width - rect.size.width) / 2,

  (baseView.frame.size.height - rect.size.height) / 2);


[self moveLabelTo:position withTitle:@"중앙" withAlignment:NSCenterTextAlignment];

}


- (IBAction)goLeftTop:(id)sender

{

CGRect rect = testLabel.frame;

CGPoint position = CGPointMake(kLabelMargineInView,

  baseView.frame.size.height - rect.size.height - kLabelMargineInView);

[self moveLabelTo:position withTitle:@"좌측 상단" withAlignment:NSLeftTextAlignment];

}


- (IBAction)goRightTop:(id)sender

{

CGRect rect = testLabel.frame;

CGPoint position = CGPointMake(baseView.frame.size.width - rect.size.width - kLabelMargineInView,

  baseView.frame.size.height - rect.size.height - kLabelMargineInView);

[self moveLabelTo:position withTitle:@"우측 상단" withAlignment:NSRightTextAlignment];

}


- (IBAction)goLeftBottom:(id)sender

{

CGPoint position = CGPointMake(kLabelMargineInView, kLabelMargineInView);

[self moveLabelTo:position withTitle:@"좌측 하단" withAlignment:NSLeftTextAlignment];

}


- (IBAction)goRightBottom:(id)sender

{

CGRect rect = testLabel.frame;

CGPoint position = CGPointMake(baseView.frame.size.width - rect.size.width - kLabelMargineInView,

  kLabelMargineInView);

[self moveLabelTo:position withTitle:@"우측 하단" withAlignment:NSRightTextAlignment];

}


@end






'OS X Programming' 카테고리의 다른 글

OS X Dev - NSButton 집중 해부 1  (0) 2012.09.02
Hello World of OS X Programming  (1) 2012.08.28
OS X Programming의 시작  (1) 2012.08.28