UIButButtonItem用UIButton作为CustomView - 来自UIButton,如何访问它的UIBarButtonItem?

sco*_*133 7 objective-c uibutton uibarbuttonitem ios

我有一个UIBarButtonItemUIButton自定义视图.

它上面UIButton有一个addTarget:action:.在动作中我提出了一个弹出窗口.我现在正在从我想要呈现的sender.frame(UIButton的框架)中呈现UIBarButtonItem.

我如何可以访问UIBarButtonItemUIButton

rob*_*off 10

如果你已经确立了自己UIButton作为customViewUIBarButtonItem,或自定义视图的孩子,那么你可以从你的按钮向上走视图层次,直到找到UIToolbarUINavigationBar包含该按钮,然后搜索栏的物品,其自定义视图的一个是按钮(或按钮的祖先).

这是我完全未经测试的代码.您可以致电[[self class] barButtonItemForView:myButton]获取包含按钮的项目.

+ (BOOL)ifBarButtonItem:(UIBarButtonItem *)item containsView:(UIView *)view storeItem:(UIBarButtonItem **)outItem {
    UIView *customView = item.customView;
    if (customView && [view isDescendantOfView:customView]) {
        *outItem = item;
        return YES;
    } else {
        return NO;
    }
}

+ (BOOL)searchBarButtonItems:(NSArray *)items forView:(UIView *)view storeItem:(UIBarButtonItem **)outItem {
    for (UIBarButtonItem *item in items) {
        if ([self ifBarButtonItem:item containsView:view storeItem:outItem])
            return YES;
    }
    return NO;
}

+ (UIBarButtonItem *)barButtonItemForView:(UIView *)view {
    id bar = view;
    while (bar && !([bar isKindOfClass:[UIToolbar class]] || [bar isKindOfClass:[UINavigationBar class]])) {
        bar = [bar superview];
    }
    if (!bar)
        return nil;

    UIBarButtonItem *item = nil;

    if ([bar isKindOfClass:[UIToolbar class]]) {
        [self searchBarButtonItems:[bar items] forView:view storeItem:&item];
    }

    else {
        UINavigationItem *navItem = [bar topItem];
        if (!navItem)
            return nil;
        [self ifBarButtonItem:navItem.backBarButtonItem containsView:view storeItem:&item]
        || [self ifBarButtonItem:navItem.leftBarButtonItem containsView:view storeItem:&item]
        || [self ifBarButtonItem:navItem.rightBarButtonItem containsView:view storeItem:&item]
        || ([navItem respondsToSelector:@selector(leftBarButtonItems)]
            && [self searchBarButtonItems:[(id)navItem leftBarButtonItems] forView:view storeItem:&item])
        || ([navItem respondsToSelector:@selector(rightBarButtonItems)]
            && [self searchBarButtonItems:[(id)navItem rightBarButtonItems] forView:view storeItem:&item]);
    }

    return item;
}
Run Code Online (Sandbox Code Playgroud)


Lor*_*o B 6

首先,你为什么需要访问UIBarButtonItem

然后,要创建一个UIBarButtonItem自定义视图,我建议您创建类似以下的类别扩展(在这种情况下,自定义视图是a UIButton).

//UIBarButtonItem+Extension.h    
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image title:(NSString*)title target:(id)target action:(SEL)action;

//UIBarButtonItem+Extension.m    
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image title:(NSString*)title target:(id)target action:(SEL)action
{
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
    button.titleLabel.textAlignment = UITextAlignmentCenter;

    [button setBackgroundImage:image forState:UIControlStateNormal];
    [button setTitle:title forState:UIControlStateNormal];
    [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];

    UIBarButtonItem* barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];

    return [barButtonItem autorelease];    
}
Run Code Online (Sandbox Code Playgroud)

并使用它(首次导入UIBarButtonItem+Extension.h):

UIBarButtonItem* backBarButtonItem = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:@"YoutImageName"] title:@"YourTitle" target:self action:@selector(doSomething:)];
Run Code Online (Sandbox Code Playgroud)

其中选择器是在使用该条形按钮项的类(目标)内实现的方法.

现在在doSomething:选择器内你可以做到以下几点:

- (void)doSomething:(id)sender

    UIButton* senderButton = (UIButton*)sender;    
    [popover presentPopoverFromRect:senderButton.bounds inView:senderButton...];
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,类别不重复代码是有用的.希望能帮助到你.

PS我没有使用ARC,但也可以应用相同的考虑因素.

编辑:

访问栏按钮项的简单解决方案可能如下:

  1. 子类a UIButton
  2. 在其中创建一个类型的属性UIBarButtonItem(一个弱的,以避免retaincycle)
  3. UIButton创建时按下条形按钮项目.

也许它可以工作,但我更喜欢第一个.