如何获取UIBarButtonItem的嵌入式按钮

8
在 iPhone 应用中,我们可以使用以下代码创建 UIBarButtonItem:
UIBarButtonItem *bbix=[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:nil action:nil];

生成的UIBarButtonItem具有系统提供的“action”图标。我的问题是:如何获取此UIBarButtonItem的内部UIButton并将此UIButton添加到另一个UIView中?谁能给我展示一些代码?

7个回答

13
你不能这样做。`UIBarButtonItem` 继承自 `UIBarItem`,后者又继承自 `NSObject`。这些类中都没有一个方法可以获取到一个 `UIButton`,因为 `UIBarButtonItem` 不是 `UIButton`。
相反地,你可以从一个 `UIButton` 创建一个 `UIBarButtonItem` -- 可以参考我在另一个问题的答案(通过将它作为“自定义视图”添加)。请参见此处获取更多信息。

它在后台有一个UIImageView,所以这是可能的。 - Nikita

6

访问“bar button item”的“customView”属性是一种可能的解决方案:

UIBarButtonItem *item = (UIBarButtonItem *)[self.navigationItem.rightBarButtonItems objectAtIndex:0];
                     OR
UIBarButtonItem *item = (UIBarButtonItem *)[self.navigationItem.rightBarButtonItem];

UIButton *myBtn;

if([item.customView isKindOfClass:[UIButton class]]) 
{ 
    myBtn = (UIButton*)item.customView;
}

if(myBtn)
{
    // do something
}

试试这个。对我来说真的很有效 :)


3

我认为你无论如何都不能获得内嵌的按钮。不过,如果你使用自定义视图创建一个按钮,例如使用按钮,我们可以使用以下代码稍后获取该按钮:

((UIButton *)(theBarButtonItem.customView.subviews.lastObject));

定制视图的层次结构应该像这样:
|--UIView
  |--UIButton
  |--UIImageView

希望这能帮到您。

1

你不能通过UIBarButtonItem访问嵌入其中的按钮

你可以使用界面生成器将内部按钮链接到新出口,这样就可以直接访问该按钮。当打开nib文件时,您可以在对象视图中找到按钮,然后将其链接到新出口。


0

如果您的UIBarButton是使用自定义视图创建的,只需扩展Brians的答案...

if ([myBarButton.customView.subviews.lastObject isKindOfClass:[UIButton class]])
{
    UIButton * btn = ((UIButton *)(myBarButton.customView.subviews.lastObject));
}

只需添加一些错误检查,因为你永远不知道苹果或其他开发者将来会何时更改布局层次结构。由于这种方法在长期内真的很容易出错。


这个方案很脆弱,很可能会出问题。由于苹果在最近几个主要的操作系统更新中对其视图层次结构进行了几次重大更改,因此我不建议使用这个解决方案。 - DiscDev

0

0

这里有一个解决方案,可以精确地复制使用UIBarButtonSystemItemAction系统类型获取的UIBarButtonItem图像。例如,新创建的UIButton被插入到MKAnnotationView中:

创建一个包含此方法的类别文件:

@implementation UIImage (Custom)

+ (UIImage *)actionButtonImage
{
    CGRect rect = CGRectMake(0, 0, 20, 27);

    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);

    [[UIColor colorWithRed:3/255.0 green:122/255.0 blue:1 alpha:1] set];

    UIBezierPath *path = [UIBezierPath bezierPath];

    // Box
    [path moveToPoint:CGPointMake(7, 8)];
    [path addLineToPoint:CGPointMake(1, 8)];
    [path addLineToPoint:CGPointMake(1, 26)];
    [path addLineToPoint:CGPointMake(19, 26)];
    [path addLineToPoint:CGPointMake(19, 8)];
    [path addLineToPoint:CGPointMake(13, 8)];

    // Arrow shaft
    [path moveToPoint:CGPointMake(10, 17)];
    [path addLineToPoint:CGPointMake(10, 1)];

    // Arrow head
    [path moveToPoint:CGPointMake(6, 4.5)];
    [path addLineToPoint:CGPointMake(10, 0.5)];
    [path addLineToPoint:CGPointMake(14, 4.5)];

    [path stroke];

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

@end

MKMapView 代理中,添加以下实现(根据需要进行调整):
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    MKPinAnnotationView *view = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"Item"];
    view.canShowCallout = YES;

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    UIImage *actionImage = [UIImage actionButtonImage];
    [button setImage:actionImage forState:UIControlStateNormal];
    button.frame = CGRectMake(0, 0, actionImage.size.width, actionImage.size.height);
    view.leftCalloutAccessoryView = button;

    return view;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接