2013-03-24 8 views
11

cercando di unità test che ho impostato l'UIBarButtonSystemItem corretto sui miei pulsanti della barra di navigazione.Ottenere UIBarButtonSystemItem indietro da UIBarButtonItem

posso ottenere lo stile indietro, ma non riesco a trovare un modo per ottenere l'UIBarButtonSystemItem

enumerazioni che sono stati fissati per il buttons.This non riesce perché lo stile è un enum diverso rispetto

la 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

Quale struttura delle asserzioni usi? –

risposta

16

su iOS 6.1, almeno (non ho ancora testato altra versione) UIBarButtonItem ha un metodo non dichiarato systemItem, che restituisce il valore passato al di inizializzazione. Si può facilmente accedere con la codifica di valori-chiave:

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); 

Se questo non funziona, è possibile creare un typedef per una struct anonima interna che è una variabile della classe UIBarButtonItem che memorizza queste informazioni esempio, e l'uso il nome del Ivar privato, e il tempo di Objective C run, come illustrato di seguito:

//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 :("); 
} 

in entrambi i casi ci si avvicina, è possibile che cambierà, quindi mi piacerebbe forse suggerire avere i test eseguiti condizionalmente solo sulle versioni di il sistema operativo verificato per supportare uno di questi approcci.

Problemi correlati