^(코딩캣)^ = @"코딩"하는 고양이;
썸네일 이미지
[iOS・iPadOS] iOS 앱에서도 안드로이드처럼 DrawerLayout(사이드 메뉴) 만들기
iOS・iPadOS 이전 게시글: 앱에 커스텀 폰트(custom font) 적용하기. iOS 앱에서도 안드로이드처럼 DrawerLayout(사이드 메뉴) 만들기 안드로이드에서는 라이브러리 차원에서 DrawerLayout, 일명 사이드 메뉴 또는 햄버거(hamburger) 버튼에 해당하는 메뉴 인터페이스가 지원되지만, iOS 쪽에는 그와 똑같은 기능이 따로 없다. iOS에서 DrawerLayout에 해당하는 인터페이스를 만들려면 써드 파티 라이브러리를 끌어오거나 다른 곳에서 코드를 복사/붙여넣기하는 방법 등 여러가지 길이 있겠으나 여기에서는 별도 라이브러리 없이 이와 유사한 인터페이스를 만들어보도록 하겠다. 1 단계. 내비게이션 뷰 컨트롤러(Navigation View Controller) 구성하기 앱 화..
API/Cocoa
2021. 8. 15. 15:10

[iOS・iPadOS] iOS 앱에서도 안드로이드처럼 DrawerLayout(사이드 메뉴) 만들기

API/Cocoa
2021. 8. 15. 15:10

iOS・iPadOS

이전 게시글: 앱에 커스텀 폰트(custom font) 적용하기.

 

iOS 앱에서도 안드로이드처럼 DrawerLayout(사이드 메뉴) 만들기

안드로이드에서는 라이브러리 차원에서 DrawerLayout, 일명 사이드 메뉴 또는 햄버거(hamburger) 버튼에 해당하는 메뉴 인터페이스가 지원되지만, iOS 쪽에는 그와 똑같은 기능이 따로 없다. iOS에서 DrawerLayout에 해당하는 인터페이스를 만들려면 써드 파티 라이브러리를 끌어오거나 다른 곳에서 코드를 복사/붙여넣기하는 방법 등 여러가지 길이 있겠으나 여기에서는 별도 라이브러리 없이 이와 유사한 인터페이스를 만들어보도록 하겠다.

 

1 단계. 내비게이션 뷰 컨트롤러(Navigation View Controller) 구성하기

앱 화면의 상단에 햄버거 버튼을 만들어야 하므로 앱의 인터페이스에 내비게이션을 적용한다. Xcode에서 기본으로 만들어 준 뷰 컨트롤러를 그대로 둔 채 [Editor] - [Embed In] - [Navigation Controller]를 클릭한다.

앱 인터페이스에 내비게이션을 적용한다.

 

Entry Point와 빈 화면 사이에 Navigation Controller가 새로 끼어들면서 기존의 빈 화면은 두 번째로 밀려났다. 이 두 번째 화면에 DrawerLayout과 비슷한 레이아웃을 구성한다. 다음과 같이 최상위 뷰(View)의 아래에 두 개의 뷰(View)를 두는데 하나의 뷰에는 기본적인 화면을 구성하고 또 다른 뷰에는 사이드 메뉴를 구성한 다음 그 두 개의 뷰를 포갠다. 사이드 메뉴로 쓰일 뷰의 폭은 다소 좁게 지정할 수 있는데 여기서는 300으로 지정한다. 좀 더 확실한 구별을 위해 사이드 메뉴로 쓰일 뷰의 배경은 오렌지 색으로 칠했다.

DrawerLayout을 고려하여 레이아웃을 작성한다.

그 다음 네비게이션 바의 좌측에 햄버거 버튼을 추가한다. 햄버거 버튼에 사용할 이미지를 구해서 넣는 과정까지는 생략한다. 혼동하지 말아야 할 것은 내비게이션 바에 추가되는 버튼의 형식은 UIBarButtonItem이라는 것이다. 이것을 내비게이션 바의 좌측에 추가한다.

내비게이션 바에 Bar Button Item을 추가한다(1).
내비게이션 바에 Bar Button Item을 추가한다(2).
내비게이션 바에 Bar Button Item을 추가한다(3).

 

2 단계. 로직 구성하기

겉 모습은 대강 위와 같이 만들어졌으므로 이제 코딩을 할 차례이다. 햄버거 버튼을 클릭할 때마다 사이드 메뉴가 나타나거나 사라지거나 해야 하는데, 이 방법에는 여러 가지가 있겠으나 여기에서는 constraint를 사용해서 사이드 메뉴의 폭을 유지한 채로 좌우로 이동시키는 방식을 사용하겠다. 다시 적으면, 평소에는 사이드 메뉴가 화면 바깥으로 완전히 나가 있다가 햄버거 버튼을 누르면 화면에 나타나도록 constraint를 조정하고 다시 햄버거 버튼을 누르면 사이드 메뉴를 화면 바깥으로 완전히 이동시키는 방식이다.

사이드 메뉴가 화면 안으로 들어왔을 때의 leading constraint.
사이드 메뉴가 화면 밖으로 벗어났을 때의 leading constraint. 

 

이와 같은 작동을 구현하기 위해 다음과 같이 최소한 2개의 IBOutlet과 1개의 IBAction이 필요하다.

class ViewController: UIViewController {
    // sidebarView의 폭을 정의하는 상수입니다.
    let sidebarViewWidth = 300
    
    // ...

    // 사이드 메뉴를 포함하고 있는 뷰(오렌지색 배경의 뷰)입니다.
    @IBOutlet var sidebarView: UIView!
    // sidebarView와 super view 사이에 적용되고 있는 Leading Constraint입니다.
    @IBOutlet var sidebarViewLeadingConstraint: NSLayoutConstraint!

    // ...

    // 햄버거 버튼을 터치할 때마다 수행될 작동이 정의된 메소드입니다.
    @IBAction func hamburgerNavigationItemTouchDown(_ sender: Any) {
        
    }
}

 

Objective-C로는 다음과 같이 적을 수 있다.

// ViewController.m
// sidebarView의 폭을 정의하는 상수입니다.
#define SIDEBAR_VIEW_WIDTH 300
// ...
@interface ViewController ()
// 사이드 메뉴를 포함하고 있는 뷰(오렌지색 배경의 뷰)입니다.
@property(atomic) IBOutlet UIView * sidebarView;
// sidebarView와 super view 사이에 적용되고 있는 Leading Constraint입니다.
@property(atomic) IBOutlet NSLayoutConstraint * sidebarViewLeadingConstraint;
@end

@implementation ViewController
// 햄버거 버튼을 터치할 때마다 수행될 작동이 정의된 메소드입니다.
- (IBAction)hamburgerNavigationItemTouchDown:(id)sender {
    
}
@end

 

ViewController 클래스에서 선언한 총 3개의 메소드 및 변수들을 스토리보드와 reference 시킨다.

코드에서 작성한 멤버와 스토리보드 요소 사이를 reference 시킨다.

 

사이드 메뉴를 화면에 나타나도록 작동하는 코드는 다음과 같이 작성한다. 사이드 메뉴 뷰와 super view 사이에 적용되는 leading constraint 값을 0으로 하면 된다.

func showSidebarView() {
    sidebarViewLeadingConstraint.constant = 0
    
    // 애니메이션 효과
    UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseIn, animations: {
        self.view.layoutIfNeeded()
    })
}

 

Objective-C로는 다음과 같이 적을 수 있다.

- (void)showSidebarView {
    self.sidebarViewLeadingConstraint.constant = 0;
    
    [UIView animateWithDuration: 0.5
                          delay: 0.0
                        options: UIViewAnimationOptionCurveEaseIn
                     animations: ^{[self.view layoutIfNeeded];}
                     completion: nil];
}

 

사이드 메뉴를 화면 밖으로 치우는 코드는 다음과 같이 작성한다. 사이드 메뉴 뷰와 super view 사이에 적용되는 leading constraint의 값을 사이드 메뉴의 폭이나 더 넓은 값으로 지정하되, 음수로 지정한다.

func hideSidebarView() {
    sidebarViewLeadingConstraint.constant = -CGFloat(sidebarViewWidth)
    
    // 애니메이션 효과
    UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseIn, animations: {
        self.view.layoutIfNeeded()
    })
}

 

Objective-C로는 다음과 같이 적을 수 있다.

- (void)hideSidebarView {
    self.sidebarViewLeadingConstraint.constant = -(CGFloat)SIDEBAR_WIDTH;
    
    [UIView animateWithDuration: 0.5
                          delay: 0.0
                        options: UIViewAnimationOptionCurveEaseIn
                     animations: ^{[self.view layoutIfNeeded];}
                     completion: nil];
}

 

햄버거 메뉴를 클릭할 때마다 사이드 메뉴에 적용된 leading constraint의 값이 음수인지 여부를 탐지하여 보이거나 감출 수 있다.

@IBAction func hamburgerNavigationItemTouchDown(_ sender: Any) {
    if (sidebarViewLeadingConstraint.constant < 0) {
        showSidebarView()
    } else {
        hideSidebarView()
    }
}

 

Objective-C로는 다음과 같이 적을 수 있다.

- (IBAction)hamburgerNavigationItemTouchDown:(id)sender {
    if (self.sidebarViewLeadingConstraint.constant < 0) {
        [self showSidebarView];
    } else {
        [self hideSidebarView];
    }
}

 

DrawerLayout(Sidebar) 작동 영상.

 

카테고리 “API/Cocoa”
more...
썸네일 이미지
[iOS・iPadOS] 앱에 커스텀 폰트(custom font) 적용하기.
iOS・iPadOS 이전 게시글: Application의 이름 localization 적용하기. 다음 게시글: iOS 앱에서도 안드로이드처럼 DrawerLayout(사이드 메뉴) 만들기 앱에 커스텀 폰트(custom font) 적용하기. 이번 시간에는 iOS 또는 iPadOS 앱에 커스텀 폰트를 내장시킨 후 이를 적용시키는 방법에 대해 정리한다. 1 단계. 커스텀 폰트 적용 전 전・후 비교를 확실하게 보기 위하여 일단 스토리보드에 적당한 텍스트를 추가한다. 시스템 폰트가 적용되어 있고, 폰트 목록에도 아직 커스텀 폰트가 나타나지 않는다. 2 단계. 커스텀 폰트 추가 앱에서 사용하고자 하는 폰트 파일을 Xcode의 프로젝트 내비게이터(Project navigator) 안으로 복사해 넣는다. 여기에서는 무난..
API/Cocoa
2021. 8. 14. 21:44

[iOS・iPadOS] 앱에 커스텀 폰트(custom font) 적용하기.

API/Cocoa
2021. 8. 14. 21:44

iOS・iPadOS

이전 게시글: Application의 이름 localization 적용하기.

다음 게시글: iOS 앱에서도 안드로이드처럼 DrawerLayout(사이드 메뉴) 만들기

 

앱에 커스텀 폰트(custom font) 적용하기.

이번 시간에는 iOS 또는 iPadOS 앱에 커스텀 폰트를 내장시킨 후 이를 적용시키는 방법에 대해 정리한다.

 

1 단계. 커스텀 폰트 적용 전

전・후 비교를 확실하게 보기 위하여 일단 스토리보드에 적당한 텍스트를 추가한다. 시스템 폰트가 적용되어 있고, 폰트 목록에도 아직 커스텀 폰트가 나타나지 않는다.

목록에 시스템 기본 폰트들만 떠 있고, 텍스트 폰트도 기본 폰트만 적용되어 있다.

 

2 단계. 커스텀 폰트 추가

앱에서 사용하고자 하는 폰트 파일을 Xcode의 프로젝트 내비게이터(Project navigator) 안으로 복사해 넣는다. 여기에서는 무난한 나눔폰트(나눔명조)를 사용해 보겠다.

나눔명조체 파일을 Xcode 프로젝트 안으로 드래그하여 넣는다.

 

3 단계. 번들에 커스텀 폰트 인식

앱에 폰트가 추가되었음을 번들(bundle) 차원에서 알고 있어야 한다. 이를 위해 ① 프로젝트 내비게이터(Project navigator) - ② 최상단 항목 - ③ TARGET에서 해당 항목을 선택한 후 ④ Info 탭을 클릭한다. Custom iOS Target Properties에서 ⑤ [+] 모양의 버튼을 클릭하여 ⑥ "Fonts provided by application"이라는 이름이 붙은 변수를 새로 추가한다.

번들에게 새 폰트가 추가되었음을 알린다(1).

 

새로 추가할 폰트의 수만큼 Item을 추가한 다음 각 Item마다 폰트 파일의 이름을 정확하게 적는다.

번들에게 새 폰트가 추가되었음을 알린다(2).

 

4 단계. UI 요소에 커스텀 폰트 적용

그 다음 스토리보드로 돌아가서 커스텀 폰트를 적용한다. 폰트를 적용할 대상을 클릭하고 폰트 유형을 System에서 Custom으로 바꾼 다음, 폰트 이름을 클릭하여 폰트 목록을 연다.

UI 요소에 커스텀 폰트를 적용한다(1).

 

폰트 목록에서 앞의 1단계에서는 없었던 폰트가 추가된 것을 확인할 수 있다. 이것으로 앱에 커스텀 폰트 적용이 끝났다.

UI 요소에 커스텀 폰트를 적용한다(2).
UI 요소에 커스텀 폰트를 적용한다(3).

카테고리 “API/Cocoa”
more...
썸네일 이미지
[iOS・iPadOS] Application의 이름 localization 적용하기.
iOS・iPadOS 다음 게시글: 앱에 커스텀 폰트(custom font) 적용하기. 앱(Application)의 이름 localization 적용하기 iPhone 또는 iPad의 언어 설정에 따라 홈 화면에 나타나는 앱의 이름을 다르게 보여주어야 할 필요가 발생할 수 있다. 예를 들어 카카오톡의 경우도 한국어 상태의 단말기에서는 홈 화면에서 앱 이름이 “카카오톡”과 같이 한글로 나타나지만, 영어 상태의 단말기에서는 앱 이름이 “KakaoTalk”과 같이 영문으로 나타난다. 사용자에게 나타나는 앱의 이름은 CFBundleDisplayName이라는 이름으로 번들(bundle)에 보관되게 된다. 위와 같은 결과를 얻으려면 Xcode에서 다음과 같이 준비한다. 1 단계. 앱이 지원할 수 있는 언어 설정하기 X..
API/Cocoa
2021. 8. 14. 18:14

[iOS・iPadOS] Application의 이름 localization 적용하기.

API/Cocoa
2021. 8. 14. 18:14

iOS・iPadOS

다음 게시글: 앱에 커스텀 폰트(custom font) 적용하기.

 

앱(Application)의 이름 localization 적용하기

iPhone 또는 iPad의 언어 설정에 따라 홈 화면에 나타나는 앱의 이름을 다르게 보여주어야 할 필요가 발생할 수 있다. 예를 들어 카카오톡의 경우도 한국어 상태의 단말기에서는 홈 화면에서 앱 이름이 “카카오톡”과 같이 한글로 나타나지만, 영어 상태의 단말기에서는 앱 이름이 “KakaoTalk”과 같이 영문으로 나타난다. 사용자에게 나타나는 앱의 이름은 CFBundleDisplayName이라는 이름으로 번들(bundle)에 보관되게 된다.

단말기의 언어가 영어로 설정된 상태에서는 앱의 이름이 영어로 표시될 수 있다.
단말기의 언어가 한국어로 설정된 상태에서는 앱의 이름이 한국어로 표시될 수 있다.
단말기의 언어가 프랑스어로 설정된 상태에서는 앱의 이름이 프랑스어로 표시될 수 있다.
단말기의 언어가 러시아어로 설정된 상태에서는 앱의 이름이 러시아어로 표시될 수 있다.
단말기의 언어가 일본어로 설정된 상태에서는 앱의 이름이 일본어로 표시될 수 있다.

 

위와 같은 결과를 얻으려면 Xcode에서 다음과 같이 준비한다.

 

1 단계. 앱이 지원할 수 있는 언어 설정하기

Xcode의 좌측 프로젝트 내비게이터(Project navigator)에서 최상단 항목인 프로젝트를 선택한다. 그 다음 우측 편집 화면에서 프로젝트 이름을 선택한 후 [Info] 탭을 클릭한다.

앱이 지원할 수 있는 언어를 설정하기(1).

 

Localization 항목을 보면 기본으로 영어만 추가되어 있는데, [+] 버튼을 눌러 앱이 지원할 수 있는 언어들을 하나씩 클릭하여 추가시킨다.

앱이 지원할 수 있는 언어를 설정하기(2).

 

언어를 선택할 때마다 프로젝트가 현재 가지고 있는 리소스 파일들의 목록이 나타나며 이러이러한 파일들에 대해 다국어를 지원하겠다는 대화상자가 나타난다. 모두 선택해 주면 좋고, 일부만 선택해서 그것들만 다국어를 지원할 수도 있다. 일단 [Finish]를 눌러본다.

앱이 지원할 수 있는 언어를 설정하기(3).

여기에서는 영어, 한국어, 프랑스어, 러시아어 및 일본어의 5개 국어를 지원해 보겠다.

앱이 지원할 수 있는 언어를 설정하기(4).

앞서 언급된 CFBundleDisplayName라는 이름의 변수는 프로젝트의 info.plist에 정의된다. 그렇다고 info.plist를 열어서 마치 하드코딩처럼 문자열을 막 수정하는 것은 재미없으므로 유연한 방법으로 접근한다.

 

2 단계. info.plist에 대한 localization 적용하기

1 단계에서 앱이 지원할 수 있는 언어들을 결정한 후에 [File] 메뉴에서 새 파일을 추가한다.

localization 파일을 추가한다(1).

새로 추가될 파일의 유형은 strings이다.

localization 파일을 추가한다(2).

 

또한 파일의 이름은 InfoPlist.strings이므로 대화상자에는 InfoPlist를 입력한다. 파일 이름은 바꾸거나 할 수 없고, Xcode에서 항상 그렇게만 쓰겠다고 고정시킨 이름이기에 여기에 따른다.

 

앞서 언급된 CFBundleDisplayName 변수는 이 곳에 놓이게 된다. strings 파일이 추가된 직후에는 대개 영어 모드일 때의 문자열을 지정하게 되므로 다음과 같이 영문 앱 이름을 우선 작성해 본다.

"CFBundleDisplayName"="<영어 앱 이름>";

CFBundleDisplayName는 대소문자가 정확히 일치해야 하며 줄 끝에는 반드시 세미콜론(;)이 붙어야 한다. 그리고나서 화면 우측 메뉴의 [Localize] 버튼을 클릭한다. 앞서 1 단계에서 앱의 언어를 추가할 때마다 이러이러한 리소스 파일에 대해 localization을 적용하겠다고 대화상자가 뜬 것을 보았을 텐데, 이와 같이 해당 대화상자에서는 나타나지 않았던 info.plist와 같은 파일이나 나중에 추가된 리소스 파일 같은 것들은 이러한 방식으로 [Localize] 버튼을 클릭하여 localization을 적용할 수 있다.

기본 앱 이름을 적고 [Localize] 버튼을 클릭(1).

 

현재 편집중인 파일은 영어 모드일 때 사용자에게 보여줄 문자열로 간주하고 영어 리소스에 해당하는 폴더로 이동시키겠다는 대화상자이다. 딱히 수정해야할 것은 없어 보이므로 그냥 [Localize] 누른다.

기본 앱 이름을 적고 [Localize] 버튼을 클릭(2).

 

그러면 [Localize] 버튼이 있던 자리에 1 단계에서 설정했던 언어 목록들이 뜬 것을 볼 수 있다. localize할 언어들을 선택해 준다. 여기에서는 모두 다 선택한다.

기본 앱 이름을 적고 [Localize] 버튼을 클릭(3).

 

언어를 체크할 때마다 프로젝트 내비게이터(Project navigator)에서 InfoPlist.string가 해당 언어 버전으로 분화되는 것을 볼 수 있다. 파일을 하나씩 열어서 그 언어에 맞게 앱 이름을 적어준다. 그러면 단말기의 언어 설정에 따라 앱 이름이 다르게 나타날 것이다.

기본 앱 이름을 적고 [Localize] 버튼을 클릭(4).

 

카테고리 “API/Cocoa”
more...
썸네일 이미지
[Xcode 오류 해결] Unable to log in with account '<Apple ID>'.
상황 Xcode로 소스 코드를 실행하는데 다음과 같은 오류가 나타난다. No signing certificate "Mac Developer" found. No "Mac Development" signing certificate matching team ID "XXXXXXXXXX" with a private key was found. The operation couldn't be completed. Unable to log in with account ''. The login details for account '' were rejected. Xcode Apple ID 로그인 오류 이런 오류가 뜨는 이유에는 여러가지가 있겠으나 이번 경우에는 Apple ID 로그인에 실패한 경우였다. 최근에 Apple ID..
API/Cocoa
2020. 4. 8. 16:17

[Xcode 오류 해결] Unable to log in with account '<Apple ID>'.

API/Cocoa
2020. 4. 8. 16:17

상황


Xcode로 소스 코드를 실행하는데 다음과 같은 오류가 나타난다.

No signing certificate "Mac Developer" found. No "Mac Development" signing certificate matching team ID "XXXXXXXXXX" with a private key was found.
The operation couldn't be completed. Unable to log in with account '<Apple ID>'. The login details for account '<Apple ID>' were rejected.
Xcode Apple ID 로그인 오류

이런 오류가 뜨는 이유에는 여러가지가 있겠으나 이번 경우에는 Apple ID 로그인에 실패한 경우였다. 최근에 Apple ID의 패스워드를 변경한 적이 있었는데, Xcode는 이전 암호로 로그인을 시도했기 때문에 Code Signing이 되지 않은 것이었다.

 

해결


[Xcode] 메뉴 옆 [Preferences...]를 클릭하여 환경 설정을 연다.

[Xcode] -> Preferences...

[Accounts]를 클릭하면 해당 Apple ID가 세션 만료된 것을 확인할 수 있다. 새로운 암호로 로그인하면 해결 완료.

암호가 바뀌어 세션 연장이 안 된 상태
카테고리 “API/Cocoa”
more...

“API/Cocoa” (4건)