본문 바로가기
ios 뽀개기/objective-c

ios 화면보호기 & 터치 감지하기

by 인생여희 2019. 4. 5.
반응형

ios 화면보호기 & 터치 감지하기

목표

iOS UIWindow에서 터치를 감지한 후 일정시간 터치가 없으면 화면보호기 viewcontroller 띄워주는 기능 구현

 

이 화면에서 3초이상 터치가 없으면 화면보호기를 띄워줄 것이다.

순서

*공통상수클래스 제작- CommonValues

설명: 화면보호기 시간을 설정해준다.

#import <Foundation/Foundation.h>

@interface CommonValues : NSObject

@property(nonatomic,assign) int SAVER_TIME;         //화면보호기 시간
@end

#import "CommonValues.h"

@implementation CommonValues
@synthesize SAVER_TIME;

- (instancetype)init
{
    self = [super init];
    if (self) {
        SAVER_TIME = 3;                                //화면보호기 설정 시간 - 3초 ;
    }
   return self;
}

@end

 

*화면보호기 클래스 제작- SViewController

설명 : 화면보호기 화면을 xib 파일로 생성한다. 그후, ui객체들을 SViewController 연결시킨다.

필요한 변수들을 생성한다. 버튼 IBAction 함수를 만들어서 버튼 or 삭제 버튼이 눌러질때 이벤트 처리를 해준다.

초기 비번은 0000. 맞으면 화면을 닫아주고, 틀리면 알림창을 띄워준다.(비밀번호 담는 변수 초기화)

비밀번호 확인 로직은 주석 참고.

화면보호기 ui


#import <UIKit/UIKit.h>

@interface SViewController : UIViewController

@end

#import "SViewController.h"

@interface SViewController ()

//숫자~ 삭제 버튼 맴버 변수
@property (weak, nonatomic) IBOutlet UIButton *one;
@property (weak, nonatomic) IBOutlet UIButton *two;
@property (weak, nonatomic) IBOutlet UIButton *three;
@property (weak, nonatomic) IBOutlet UIButton *four;
@property (weak, nonatomic) IBOutlet UIButton *five;
@property (weak, nonatomic) IBOutlet UIButton *six;
@property (weak, nonatomic) IBOutlet UIButton *seven;
@property (weak, nonatomic) IBOutlet UIButton *eight;
@property (weak, nonatomic) IBOutlet UIButton *nine;
@property (weak, nonatomic) IBOutlet UIButton *zero;
@property (weak, nonatomic) IBOutlet UIButton *deleteButton;

//비번
@property (weak, nonatomic) IBOutlet UITextField *textfield;
@property(nonatomic,strong)NSString *secretKey;
@end

@implementation SViewController

//세로 화면만 허용 하기
- (NSUInteger) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait; //세로 화면만 허용
}

- (void)viewDidLoad {
    [super viewDidLoad];
    //비번 초기화
    _secretKey = [[NSString alloc]init];
}



// 숫자키 ~ del 눌렀을때
- (IBAction)numBtnAction:(id)sender {
    
    //삭제키 눌렀을때
    if([[sender titleLabel].text isEqualToString:@"del"]){
        //비밀번호 개수가 한개 이상일때
        if ([_secretKey length] > 0) {
            //하나씩 지워 주기
            _secretKey = [_secretKey substringToIndex:[_secretKey length] - 1];
            
            self.textfield.text = _secretKey;
        } else {
            return;
        }
    }else{
        
        //숫자키 눌렀을 때 숫자하나씩더하기
        _secretKey = [_secretKey stringByAppendingString:[sender titleLabel].text];
        self.textfield.text = _secretKey;

        //비밀번호 개수가 4개 일때
        if (_secretKey.length > 3) {
            //비번체크 : 비번을 0000 라고 해준다.
            if([_secretKey isEqualToString:@"0000"]){
                
                //화면보호기 창 내려주기
                [self dismissViewControllerAnimated:YES completion:nil];
            }else{
                
                //비밀번호 틀림창 띄워주기
                UIAlertController * view=   [UIAlertController
                                                             alertControllerWithTitle:@"알림"
                                                             message:@"비밀번호를 확인해주세요"
                                                             preferredStyle:UIAlertControllerStyleActionSheet];
                
                UIAlertAction* ok = [UIAlertAction
                                                 actionWithTitle:@"확인"
                                                 style:UIAlertActionStyleDefault
                                                 handler:^(UIAlertAction * action)
                                                 {
                                                     [view dismissViewControllerAnimated:YES completion:nil];
                                                 }];
                
                [view addAction:ok];
                [self presentViewController:view animated:YES completion:^{
                    self.textfield.text = @"";
                    self->_secretKey = [[NSString alloc]init];
                }];
                
            }//
        }//
    }
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

*화면보호기를 띄울 클래스 제작- DetectTouchWindow

 화면 보호기를 컨트롤 하는 클래스는 UIWindow를 상속 받는다. NSTimer  객체변수와 UIWindow 객체 변수등 필요한 변수를 생성한다. 

idleTimerExceeded 함수: 타이머가 일정시간이 지났을때 호출되는 함수.화면보호기를 띄워준다.

resetIdleTimer 함수 : 터치가 인식되면 타이머를 계속 초기화 시켜준다. 터치가 안되면 타이머는 계속 진행된다.

sendEvent 함수: 터치 시작 or 터치 종료에 호출되는 함수


#import <UIKit/UIKit.h>
#import "SViewController.h"

@interface DetectTouchWindow : UIWindow                     //화면 보호기를 컨트롤 하는 클래스는 UIWindow를 상속 받는다.
@property (strong,nonatomic) NSTimer *idleTimer;         //타이머 객체
@property (strong, nonatomic) UIWindow *window;       //UIWindow 객체
@property (nonatomic,assign) int screenSaverTime;      //화면보호기가 나타날 시간(터치가 없고난 뒤 몇 시간뒤?)

@end
#import "DetectTouchWindow.h"
#import "CommonValues.h"
@implementation DetectTouchWindow
@synthesize idleTimer,screenSaverTime;



- (void)sendEvent:(UIEvent *)event {
    [super sendEvent:event];
    // 타이머 재설정 횟수를 줄이기 위해 시작 터치 또는 종료 터치에서만 타이머를 재설정.
    NSSet *allTouches = [event allTouches];
    
    // 눌렀을때 1, 누르고 손가락을 땔때 resetIdleTimer 를 호출한다.
    NSLog(@"sendEvent : %lu" , (unsigned long)[allTouches count]);
    if ([allTouches count] > 0) {
       
        //allTouches 수는 1로만 계산되므로 anyObject가 여기에서 작동합니다.
        UITouchPhase phase = ((UITouch *)[allTouches anyObject]).phase;
        if (phase == UITouchPhaseBegan || phase == UITouchPhaseEnded)
        [self resetIdleTimer];
    }
}

//터치가 되면 호출되는 함수 - 터치 중
- (void)resetIdleTimer {
    if (idleTimer) {
        NSLog(@"DetectTouchWindow - 터치가 감지되는 중...");
        [idleTimer invalidate]; //타이머 제거 = 타이머 초기화
    }
    
    //공통 상수 함수 - 화면보호기 시간
    CommonValues *cmVal = [[CommonValues alloc]init];
    screenSaverTime = cmVal.SAVER_TIME;
    //일정 시간뒤 화면보호기 창 띄우기 - 터치가 되면 계속 일정 시간으로 초기화 됨.
    idleTimer = [NSTimer scheduledTimerWithTimeInterval:screenSaverTime target:self selector:@selector(idleTimerExceeded) userInfo:nil repeats:NO] ;
}

- (void)idleTimerExceeded {
    NSLog(@"DetectTouchWindow - 화면 보호기 창을 띄웁니다.");
    
    //현재 띄워진 class 의 이름 - 특정 클래스 걸러내기
    UIViewController *curentViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
    NSString *currentSelectedCViewController = NSStringFromClass([[((UINavigationController *)curentViewController) visibleViewController] class]);
    
    //사진촬영 중일때, 녹음중일때 제외하고 화면보호기 띄우기 - !
    if([currentSelectedCViewController isEqualToString:@"CaptureMedia"]){
         [self resetIdleTimer];     //화면 보호기 시간 계속 초기화(터치중임)
    }else if([currentSelectedCViewController isEqualToString:@"AudioRecorder"]){
         [self resetIdleTimer];
    }else if([currentSelectedCViewController isEqualToString:@"MediaView"]){
        [self resetIdleTimer];
    }else{

       
        //위의 클래스들이 아닐때 화면보호기 띄우기
        NSString *s_key = @"1234";
        if (s_key) {
            NSLog(@"화면보호기를 띄웁니다 ₩~~~~~~~  %@ " , s_key);
            
            //일정시간 이상 지나면 커스텀으로 만든 화면 보호기 띄워주기
            SViewController *sv = [[SViewController alloc]init];
           [[[UIApplication.sharedApplication keyWindow]rootViewController] presentViewController:sv animated:YES completion:nil];
       
            
//            UIViewController *activeController = [UIApplication sharedApplication].keyWindow.rootViewController;
//            if ([activeController isKindOfClass:[UINavigationController class]])
//                activeController = [(UINavigationController*) activeController visibleViewController];
//            else if (activeController.presentedViewController)
//                activeController = activeController.presentedViewController;
//            [activeController presentViewController:sv animated:YES completion:nil];

        }else{
            NSLog(@"화면보호기를 띄우지 않습니다~~~~~~~~~ %@ " , s_key);
        }

    }
   
}


@end

*앱 댈리게이트에 설정해주기 제작- AppDelegate

설명: 위에서 만든 클래스들을 객체로 만들어서 셋팅해준다. main 컨트롤러에 터치가 시작되면 DetectTouchWindow에서 반응을 한 뒤 카운터를 시작한다. 터치가 또 있으면 DetectTouchWindow의 sendEvent, idleTimerExceeded 함수가 호출 되면서 카운터가 초기화 된다. 일정 시간 터치가 없으면 타이머가 완료(초기화 x 정상종료)되면서 화면보호기가 뜬다. 

#import "AppDelegate.h"
#import "CommonValues.h"
#import "DetectTouchWindow.h"
#import "ViewController.h"
@interface AppDelegate ()
@property (strong,nonatomic) ViewController *vc;
@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    _window = [[DetectTouchWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    UIStoryboard *sboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    ViewController *vc = [sboard instantiateInitialViewController];
    
    UINavigationController *nc = [[UINavigationController alloc]initWithRootViewController:vc];
    
    [_window setBackgroundColor:[UIColor yellowColor]];
    [_window setRootViewController:nc];
    [_window makeKeyAndVisible];
    
    return YES;
}


@end

 

예제파일

DtectView.zip
0.08MB

반응형

댓글