Skip to the content.

watchOS에서 UICollectionView를 써보자 (PUICCollectionViewController)

이전 포스트 watchOS에서 UIKit 사용에 이어서… watchOS에서 UICollectionView (엄밀히 말하면 PUICCollectionView)를 써보는 방법을 소개하려고 해요.

이런 해괴한 짓을 하는 이유는 WKInterfaceTable로는 복잡한 레이아웃은 구현이 불가능하고 NSDiffableDataSourceSnapshot도 쓸 수 있다는 엄청난 장점이 있어요. (사실 SwiftUI 쓰면 되긴 함…)

watchOS에는 PepperUICore라고 하는 Private Framework가 존재하고, 그 안에 PUICCollectionViewController가 있어요. 이걸 쓰기 위해 PepperUICore.tbd가 필요해요. 이걸 얻기 위해서는 제가 만든 create_patched_sdk_watchos.sh를 쓰시거나 이 방법을 따라 하시면 되는데… 귀찮으면 제가 여기에 올려놨으니 받으셔도 돼요.

watchOS Simalator를 쓰시는 경우, tdb 안에 있는 `install-name` 값을 RuntimeRoot애 있는 PepperUICore Mach-O 파일의 경로로 수정해 주셔야 할 수도 있어요.

그 다음에 아래 사진처럼 PepperUICore.tbd를 Xcode에서 아래처럼 등록해 주세요.

자 이제 PUICCollectionViewController.h를 아래처럼 만들어 주시고, PUICCollectionViewController를 subclassing해서 원하시는 View Controller를 만들어 보세요.

#import <Foundation/Foundation.h>

@interface PUICCollectionViewController : NSObject
@end

저는 PUICCollectionViewController를 subclassing하는 CardBacksViewController를 만들었는데요. 이제 이걸 WKInterfaceController에서 띄워볼게요.

#import <WatchKit/WatchKit.h>
#import "CardBacksViewController.h"

@interface InterfaceController : WKInterfaceController
@end

@implementation InterfaceController

- (void)willActivate {
    [super willActivate];
    
    id application = [NSClassFromString(@"SPApplication") sharedApplication];
    id delegate = [application delegate];
    id window = [delegate window];
    id rootViewController = [window rootViewController]; // PCUINavigationController
    
    CardBacksViewController *vc = [CardBacksViewController new];
    [rootViewController setViewControllers:@[vc] animated:NO];
    [vc release];
}

@end

이제 실행해보면…

고화질 (YouTube)

너무 잘 된다😭 PepperUICore에 대해 아는게 없고 검색해도 안 나오다보니 이거 성공시키려고 7시간 동안 삽질 ㅠㅠ PUICCrownInputSequencer도 자동으로 잘 붙어서 Digital Crown을 통한 스크롤도 잘 되는 걸 볼 수 있어요…

참고로 제 StoneNamu 프로젝트에서 해당 부분의 코드를 볼 수 있어요.

PUICCollectionViewUICollectionView에는 없는 전용 기능들이 존재하고, UIScrollView(PUICAdditions)라는 Category도 존재해요. lldb로 보시면 iOS에는 볼 수 없는 재밌는 것들이 여러가지 있어서 관심 있으시면 보시는 것도 좋아요.

여담

App Store에 올렸더니 Reject 당하네요… ㅎㅎ Objective-C Runtime로 꼼수부리면 피할 수 있을 것 같긴 하네요.