如何获取 UIBarButtonItem 的嵌入按钮

Posted

技术标签:

【中文标题】如何获取 UIBarButtonItem 的嵌入按钮【英文标题】:How to get the embedded button of UIBarButtonItem 【发布时间】:2010-06-13 07:38:22 【问题描述】:

在 iPhone 应用中,我们可以使用以下代码制作 UIBarButtonItem:

UIBarButtonItem *bbix=[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:nil action:nil];

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

【问题讨论】:

【参考方案1】:

你不能。 UIBarButtonItem 继承自 UIBarItem,后者继承自 NSObject。这些类都没有获取UIButton 的方法,因为UIBarButtonItem 不是UIButton

相反,您可以从 UIButton 创建一个 UIBarButtonItem - 请参阅 an answer I gave to a different question 了解更多信息(通过将其添加为“自定义视图”来工作)。

【讨论】:

它在幕后有一个 UIImageView,所以这是可能的【参考方案2】:

访问栏按钮项的“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

希望有所帮助。

【讨论】:

【参考方案4】:

您无法通过 UIBarButtonItem 访问 UIBarButtonItem 内的嵌入按钮

您可以使用界面构建器将内部按钮与新插座链接起来,这样您可以直接访问按钮 当您打开 nib 文件时,您可以在对象视图中找到该按钮,然后您可以将其链接到新的插座

【讨论】:

【参考方案5】:

如果你的 UIBarButton 是用自定义视图制作的,只是为了扩展 Brians 的答案......

if ([myBarButton.customView.subviews.lastObject isKindOfClass:[UIButton class]])

    UIButton * btn = ((UIButton *)(myBarButton.customView.subviews.lastObject));

只需添加一点错误检查,您永远不知道苹果或其他开发人员何时会更改布局层次结构。因为从长远来看,这种方法真的很容易出错。

【讨论】:

这很脆弱,很可能会折断。 Apple 在最近几次主要的操作系统更新中对其视图层次结构进行了几项重大更改,因此我不推荐此解决方案。【参考方案6】:

如果您通过 initWithCustomView 创建了条形按钮项,只需访问自定义视图属性并转换为 UIButton。

http://cocoatouch.blog138.fc2.com/blog-entry-214.html

【讨论】:

【参考方案7】:

这是一个精确复制UIBarButtonItem 图像的解决方案,否则使用UIBarButtonSystemItemAction 系统类型获取该图像。例如,将新创建的 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;

【讨论】:

以上是关于如何获取 UIBarButtonItem 的嵌入按钮的主要内容,如果未能解决你的问题,请参考以下文章

UIBarButtonItem 的 UIButton 扩展

按下 UIBarButtonItem 时如何检测?

UIBarButtonItem 形状不正确

IOS swift UIBarButtonItem 动作

在 Swift 中获取 UIBarButtonItem 的视图

UIBarButtonItem 中的 UISlider 影响动画行为