2013-03-24 1 views
11

단위 테스트를 시도하면 navbar 버튼에 올바른 UIBarButtonSystemItem이 설정되었습니다.UIBarButtonItem에서 UIBarButtonSystemItem을 다시 가져 오십시오.

내가 다시 스타일을 얻을 수 있지만 스타일이

댄 다른 열거이기 때문에 UIBarButtonSystemItem

열거 buttons.This 설정 한 실패를 얻을 수있는 방법을 찾을 수 없습니다

UIBarButtonSystemItem :

- (void)test_init_should_set_left_right_barButtonItems { 

    UIBarButtonItem *left = mainVCSUT.navigationItem.leftBarButtonItem; 
    UIBarButtonItem *right = mainVCSUT.navigationItem.rightBarButtonItem; 
    [Assert isNotNil:left]; 
    [Assert isNotNil:right]; 

    UIBarButtonItemStyle leftStyle = left.style; 
    UIBarButtonItemStyle rightStyle = right.style; 

    [Assert that:[The int:leftStyle] is:[Equal to:[The int:UIBarButtonSystemItemRefresh]]]; 
    [Assert that:[The int:rightStyle] is:[Equal to:[The int:UIBarButtonSystemItemSearch]]]; 
} 
+0

어떤 어설 션 프레임 워크를 사용합니까? –

답변

16

아이폰 OS 6.1에 (내가 다른 버전을 테스트하지 않았습니다) UIBarButtonItem가 초기화에 전달 된 값을 반환 선언되지 않은 방법 systemItem을 가지고 적어도. 그래도 문제가 해결되지 않으면이 정보를 저장하는 UIBarButtonItem 클래스의 인스턴스 변수의 내부 익명 구조체에 대한 형식 정의를 만들 수 있습니다,

UIBarButtonSystemItem systemItemIn = UIBarButtonSystemItemAdd; 
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:systemItemIn target:nil action:NULL]; 
NSNumber *value = [item valueForKey:@"systemItem"]; 
UIBarButtonSystemItem systemItemOut = [value integerValue]; 
NSLog(@"systemItemIn = %d, systemItemOut = %d", systemItemIn, systemItemOut); 

를 사용 : 당신은 쉽게 키 - 값 코딩에 액세스 할 수 있습니다 아래 그림과 같이 개인 바르의 이름, 목표 C 런타임 :

//Copied from UIBarButtonItem.h, this is the struct used for the _barButtomItemFlags ivar 
typedef struct { 
    unsigned int enabled:1; 
    unsigned int style:3; 
    unsigned int isSystemItem:1; 
    unsigned int systemItem:7; 
    unsigned int viewIsCustom:1; 
    unsigned int isMinibarView:1; 
    unsigned int disableAutosizing:1; 
    unsigned int selected:1; 
    unsigned int imageHasEffects:1; 
} FlagsStruct; 

// In our test code 
// Instantiate a bar button item 
UIBarButtonSystemItem systemItemIn = UIBarButtonSystemItemAdd; 
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:systemItemIn target:nil action:NULL]; 

// Set up variables needed for run time functions 
Class barItemClass = [item class]; 
BOOL foundIt = NO; // We check this flag to make sure we found the ivar we were looking for 
ptrdiff_t ivarOffset = 0; // This will be the offset of _barButtomItemFlags within the bar button item object 

// Iterate through all of UIBarButtonItem's instance variables 
unsigned int ivarCount = 0; 
Ivar *ivarList = class_copyIvarList(barItemClass, &ivarCount); 
for (int i = 0; i < ivarCount; i++) { 
    Ivar ivar = ivarList[i]; 
    const char *ivarName = ivar_getName(ivar); 
    if (!strcmp(ivarName, "_barButtonItemFlags")) { 
     // We've found an ivar matching the name. We'll get the offset and break from the loop 
     foundIt = YES; 
     ivarOffset = ivar_getOffset(ivar); 
     break; 
    } 
} 
free(ivarList); 

if (foundIt) { 
    // Do a little pointer math to get the FlagsStruct - this struct contains the system item value. 
    void *itemPointer = (__bridge void *)item; 
    FlagsStruct *flags = itemPointer + ivarOffset; 
    UIBarButtonSystemItem systemItemOut = flags->systemItem; 
    NSLog(@"systemItemIn = %d, systemItemOut = %d", systemItemIn, systemItemOut); 
    BOOL equal = (systemItemIn == systemItemOut); 
    if (equal) { 
     NSLog(@"yes they are equal"); 
    } 
    else { 
     NSLog(@"no they are not"); 
    } 
} 
else { 
    // Perhaps Apple changed the ivar name? 
    NSLog(@"didn't find any such ivar :("); 
} 
당신이 그것을 접근

어느 쪽이든, 그것은이 변경됩니다 가능한, 그래서 어쩌면 당신의 테스트 만의 버전에서 조건부 실행을 갖는 게 좋을 것 OS는 이러한 접근법 중 하나를 지원하도록 검증되었습니다.

관련 문제