首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从UIBarButtonItem取回UIBarButtonSystemItem

从UIBarButtonItem取回UIBarButtonSystemItem
EN

Stack Overflow用户
提问于 2013-03-25 04:05:48
回答 1查看 3.9K关注 0票数 13

尝试单元测试我在导航栏按钮上设置了正确的UIBarButtonSystemItem。

我可以找回样式,但似乎找不到获得UIBarButtonSystemItem的方法

为buttons.This设置的枚举失败,因为样式不同于

UIBarButtonSystemItem:

代码语言:javascript
复制
- (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]]];
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-25 09:32:06

至少在iOS 6.1上(我还没有测试过其他版本),UIBarButtonItem有一个未声明的方法systemItem,它返回传递给初始化器的值。您可以通过键值编码轻松访问它:

代码语言:javascript
复制
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);

如果这不起作用,您可以为内部匿名结构创建一个类型定义,该内部匿名结构是存储此信息的UIBarButtonItem类的实例变量,并使用私有ivar的名称和Objective C运行时,如下所示:

代码语言:javascript
复制
//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 :(");
}

无论您采用哪种方法,都有可能会发生变化,所以我可能会建议您只在经过验证支持这两种方法的操作系统版本上有条件地运行测试。

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15603375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档