2012년 8월 9일 목요일

iOS 프로그래밍 팁 - 10 웹페이지를 보여주는 ViewController 만들기

그냥 UIWebView를 사용하는건데
UIActivityIndicatorView를 좀 써서 페이지 여는 동안 가운데 에서 동글 동글 돌리려면
UIWebViewDelegate 프로토콜 메서드 두개를 구현해주고
UIActivityIndicatorView를 start/ stop 해주면 된다.


헤더 파일


#import <UIKit/UIKit.h>

@interface WebViewController : UIViewController <UIWebViewDelegate> {
    
    UIActivityIndicatorView *webActInd;
}

@end

m파일
- (void)viewDidLoad
{
    [super viewDidLoad];
    //Web URL View 
    UIWebView *webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 45, 320, 415)];
    [webView setDelegate:self];
    
 NSString *url = @"http://mtsparrow.blogspot.kr";
    
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
    [self.view addSubview:webView];
    [webView release];
}



- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    // 액티비티인디케이터 설정
webActInd = [[UIActivityIndicatorView alloc
  initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[webActInd setFrame:CGRectMake(0.0, 0.0, 50.0, 50.0)];
    [webActInd setCenter:CGPointMake(320/2, 480/2)];
[self.view addSubview:webActInd];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // Do any additional setup after loading the view.
    webActInd = nil;

}

- (void)dealloc
{
    [super dealloc];
    
    [webActInd release];
}


// 뷰를 부르기 시작
- (void)webViewDidStartLoad:(UIWebView *)webView {
[webActInd startAnimating];
}

// 뷰가 화면에 표시
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    
[webActInd stopAnimating];
}



2012년 8월 8일 수요일

iOS 프로그래밍 팁 - 9 UITextFiled의 글쓰기 시작할때 UI 올리고 내리기

UITextFiled가 들어가는 앱 즉.. 유틸 같은 앱을 배포한 적이 없다.
그래서 이러한 부분을 잘몰랐다.

간단한 보드 게임을 주로 만들기 때문에 ...

그래도 ID입력받고  Password입력받고 등등..

이러한 간단한 입력 작업은 많을 것이고 입력 시작 과함께 키보드가 나오고
입력 창은 같이 위로 올라 가야 한다.

키보드에 가리면 낭패...


- (void)textViewDidBeginEditing:(UITextView *)textView {
    self.view.frame = CGRectMake(0, -200, self.view.frame.size.width, self.view.frame.size.height);
}

입력이 시작될 때 view 를 200 만큼 위로 올리는 것이다.

그리고 화면 아무 데나 누르면 다시 내려가고 원위치를 해야 할 것이다.

- (void)textViewDidEndEditing:(UITextView *)textView{
    self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}

아무 데나 누르면?
아래와 같이 해주면 된다.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [txtFieldID resignFirstResponder];
    [txtFieldPasswd resignFirstResponder];
    [self.view endEditing:YES]; 
}









2012년 8월 7일 화요일

iOS 프로그래밍 팁 - 8 카드 뒤집기 효과

닥치고 기억 앱에서 사용된 카드를 선택하면 앞 그림이 보였다가 다시 원래 뒷 그림으로
일반적인 같은 짝 찾기 게임에서 사용하는 방법이다.

[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:btn cache:YES];
는 사실 뷰콘트롤러 전환시에 유틸리티의 경우 정보 버튼을 누르면 일반적으로 이효과 로
뷰 콘트롤러가 넘어가게 많이 만든다.
이를 버튼에 이미지에 적용해서 카드 게임에서 카드 뒤집기 효과를 내는 것이다.



btnClick 메서드에서

toFrontBtnImage 메서드를 호출하고

toFrontBtnImage 메서드는 앞면으로 바뀌는 에니메이션을

만일 정답이라면 그대로
틀린 경우
toBackBtnImage 메서드르 호출 해서 뒷면으로 바뀌느 에니메이션을
하면 된다.

toFrontBtnImage의 구현

img = [UIImage imageNamed:fileName];         //<--- 앞면 이미지 얻기
    flagSide[btn.tag] = FRONT;
   
    CGPoint startpoint = CGPointMake(0, 0);
    [img drawAtPoint:startpoint];

    [UIView beginAnimations:@"toFrontBtnImage" context:nil];
    [UIView setAnimationDuration:ANIMATION_DURATION];
   
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:btn cache:YES]; <-- 뒤집기 효과
   
    [btn setImage:img forState:UIControlStateNormal];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
    [UIView commitAnimations];

toBackBtnImage의 구현
같은 방법으로 이미 정의된 뒷면 그림 파일을 이용


 UIImage * img;
    img = [UIImage imageNamed:@"back.png"];
    flagSide[btn.tag] = BACK;
   
    CGPoint startpoint = CGPointMake(0, 0);
    [img drawAtPoint:startpoint];
   
    [UIView beginAnimations:@"toBackBtnImage" context:nil];
    [UIView setAnimationDuration:ANIMATION_DURATION];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; // 빠져나갈때 가속
   
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:btn cache:YES];
   
    [btn setImage:img forState:UIControlStateNormal];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
    [UIView commitAnimations];

animationDidStop 메서드에서는 정답일때 오답일때를 검출해서 toBackBtnImage를 다시 호출 하거나
정답일때 처리를 구현 해주면 된다.



2012년 8월 6일 월요일

iOS 프로그래밍 팁 - 7 UIPlaceHolderTextView

UITextField 는 placeholder 프로퍼티가 존재한다.
입력전에 grayColor로 보여주다가 입력이 시작되면 사라지는 것이다.

근데 멀티라인을 입력 할수 있는 UITextView는 이러한 placeholder프로퍼티가 없다.

UITextView 를 상속 받고 NSString *placeholder, 와 UIColor *placeholderColor 를
가지고 있는 UIPlaceHolderTextView를 만들어 사용할수 있다.

UIPlaceHolderTextView.h

#import <Foundation/Foundation.h>


@interface UIPlaceHolderTextView : UITextView {
    NSString *placeholder;
    UIColor *placeholderColor;
    
@private
    UILabel *placeHolderLabel;
}

@property (nonatomic, retain) UILabel *placeHolderLabel;
@property (nonatomic, retain) NSString *placeholder;
@property (nonatomic, retain) UIColor *placeholderColor;

-(void)textChanged:(NSNotification*)notification;

@end

UIPlaceHolderTextView.m
#import "UIPlaceHolderTextView.h"


@implementation UIPlaceHolderTextView

@synthesize placeHolderLabel;
@synthesize placeholder;
@synthesize placeholderColor;

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [placeHolderLabel release]; placeHolderLabel = nil;
    [placeholderColor release]; placeholderColor = nil;
    [placeholder release]; placeholder = nil;
    [super dealloc];
}

- (void)awakeFromNib
{
    [super awakeFromNib];
    [self setPlaceholder:@""];
    [self setPlaceholderColor:[UIColor lightGrayColor]];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil];
}

- (id)initWithFrame:(CGRect)frame
{
    if( (self = [super initWithFrame:frame]) )
    {
        [self setPlaceholder:@""];
        [self setPlaceholderColor:[UIColor lightGrayColor]];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil];
    }
    return self;
}

- (void)textChanged:(NSNotification *)notification
{
    if([[self placeholder] length] == 0)
    {
        return;
    }
    
    if([[self text] length] == 0)
    {
        [[self viewWithTag:999] setAlpha:1];
    }
    else
    {
        [[self viewWithTag:999] setAlpha:0];
    }
}

- (void)setText:(NSString *)text {
    [super setText:text];
    [self textChanged:nil];
}

- (void)drawRect:(CGRect)rect
{
    if( [[self placeholder] length] > 0 )
    {
        if ( placeHolderLabel == nil )
        {
            placeHolderLabel = [[UILabel alloc] initWithFrame:CGRectMake(8,8,self.bounds.size.width - 16,0)];
            placeHolderLabel.lineBreakMode = UILineBreakModeWordWrap;
            placeHolderLabel.numberOfLines = 0;
            placeHolderLabel.font = self.font;
            placeHolderLabel.backgroundColor = [UIColor clearColor];
            placeHolderLabel.textColor = self.placeholderColor;
            placeHolderLabel.alpha = 0;
            placeHolderLabel.tag = 999;
            [self addSubview:placeHolderLabel];
        }
        
        placeHolderLabel.text = self.placeholder;
        [placeHolderLabel sizeToFit];
        [self sendSubviewToBack:placeHolderLabel];
    }
    
    if( [[self text] length] == 0 && [[self placeholder] length] > 0 )
    {
        [[self viewWithTag:999] setAlpha:1];
    }
    
    [super drawRect:rect];
}

@end


참고 : http://stackoverflow.com/questions/1328638/placeholder-in-uitextview



2012년 8월 5일 일요일

iOS 프로그래밍 팁 - 6 UITextFieldDelegate Protocol Methods 작업하기

UITextField를 작업할때 클래스 선언에 <UITextFieldDelegate> 해준 다음 다음과 같이 
메소드들을 구현해줘야 한다.



#pragma mark UITextFieldDelegate Protocol Methods
// 텍스트 필드의 내용이 변경될 실행된다.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
//textField 의 text.length >= 100 등으로 글자 수 제한을 할수 있다.

//특수 문자 입력 제한도 할수 있다.
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:LEGAL] invertedSet];
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];

return [string isEqualToString:filtered];


    return YES; // NO 리턴할 경우 변경내용이 반영되지 않는다.
}

// 텍스트 필드의 내용이 삭제될 실행된다. clearButtonMode 속성값이 UITextFieldViewModeNever 아닌 경우에만 실행된다.
- (BOOL)textFieldShouldClear:(UITextField *)textField
{
    
    return YES; // NO 리턴할 경우 변경내용이 반영되지 않는다.
}

// 텍스트 필드 편집을 시작할때 실행된다.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    
    return YES; // 편집을 허용하지 않고자 경우 NO 리턴한다.
}

// 텍스트 필드 편집이 시작된 (First Responder ) 실행된다.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    
}

// 텍스트 필드 편집이 종료될때 실행된다.
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
    
    
    return YES; // NO 리턴할 경우 편집을 종료하지 않는다.
}

// 텍스트 필드 편집이 종료된 후에 실행된다.
- (void)textFieldDidEndEditing:(UITextField *)textField
{
}



-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    
    // return 키가 눌려지면 return키가 눌려진 텍스트 필드의 FirstResponder 해제한다
    
    [textField resignFirstResponder];
    
    return YES;
    
}