UIBarButtonItem:我怎样才能找到它的框架?

时间:2013-01-14 12:25:39

标签: ios objective-c swift

我在工具栏中有一个按钮。我怎么能抓住它的框架? UIBarButtonItem没有frame属性吗?

16 个答案:

答案 0 :(得分:88)

试试这个;

UIBarButtonItem *item = ... ;
UIView *view = [item valueForKey:@"view"];
CGFloat width;
if(view){
    width=[view frame].size.width;
}
else{
    width=(CGFloat)0.0 ;
}

答案 1 :(得分:19)

这种方式最适合我:

UIView *targetView = (UIView *)[yourBarButton performSelector:@selector(view)];
CGRect rect = targetView.frame;

答案 2 :(得分:12)

感谢Anoop Vaidya的建议答案。另一种方法是(让您知道工具栏中按钮的位置)

UIView *view= (UIView *)[self.toolbar.subviews objectAtIndex:0]; // 0 for the first item


CGRect viewframe = view.frame;

答案 3 :(得分:9)

使用 Swift ,如果您需要经常使用条形按钮项,则应实现如下扩展名:

extension UIBarButtonItem {

    var frame: CGRect? {
        guard let view = self.value(forKey: "view") as? UIView else {
            return nil
        }
        return view.frame
    }

}

然后在您的代码中,您可以轻松访问:

if let frame = self.navigationItem.rightBarButtonItems?.first?.frame {
    // do whatever with frame            
}

答案 4 :(得分:8)

Oof,在这个帖子中有很多粗略的答案。这是正确的方法:

import UIKit

class ViewController: UIViewController {

    let customButton = UIButton(type: .system)

    override func viewDidLoad() {
        super.viewDidLoad()

        customButton.setImage(UIImage(named: "myImage"), for: .normal)
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: customButton)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        print(self.customButton.convert(self.customButton.frame, to: nil))
    }
}

答案 5 :(得分:2)

-(CGRect) getBarItemRc :(UIBarButtonItem *)item{
    UIView *view = [item valueForKey:@"view"];
    return [view frame];
}

答案 6 :(得分:2)

这就是我在iOS 11和Swift 4中使用的内容。如果没有可选选项,可能会更干净一些,但是我正在安全地使用它

extension UIBarButtonItem {
    var view: UIView? {
        return perform(#selector(getter: UIViewController.view)).takeRetainedValue() as? UIView
    }
}

和用法:

if let barButtonFrame = myBarButtonItem.view?.frame {
    // etc...
}

答案 7 :(得分:1)

尝试此实施:

@implementation UIBarButtonItem(Extras)

- (CGRect)frameInView:(UIView *)v {

    UIView *theView = self.customView;
    if (!theView.superview && [self respondsToSelector:@selector(view)]) {
        theView = [self performSelector:@selector(view)];
    }

    UIView *parentView = theView.superview;
    NSArray *subviews = parentView.subviews;

    NSUInteger indexOfView = [subviews indexOfObject:theView];
    NSUInteger subviewCount = subviews.count;

    if (subviewCount > 0 && indexOfView != NSNotFound) {
        UIView *button = [parentView.subviews objectAtIndex:indexOfView];
        return [button convertRect:button.bounds toView:v];
    } else {
        return CGRectZero;
    }
}

@end

答案 8 :(得分:0)

您应该对子视图进行循环,并检查其类型或其内容以进行识别。 通过kvo访问视图是不安全的,你无法确定索引。

答案 9 :(得分:0)

看看这个答案:How to apply borders and corner radius to UIBarButtonItem?,它解释了如何循环子视图以找到按钮的框架。

答案 10 :(得分:0)

您可以使用自定义视图创建UIBarButtonItem,这是一个UIButton,然后您可以执行任何操作。 :

答案 11 :(得分:0)

这是这样做的方法:

-(CGRect)findFrameOfBarButtonItem{
    for (UIView *view in self.navigationController.navigationBar.subviews)
    {
       if ([view isKindOfClass:NSClassFromString(@"_UINavigationBarContentView")])
       {
         UIView * barView = [self.navigationItem.rightBarButtonItem valueForKey:@"view"];
         CGRect barFrame = barView.frame;
         CGRect viewFrame = [barView convertRect:barFrame toView:view];
         return viewFrame;
       }
    }

    return CGRectZero;
}

答案 12 :(得分:0)

在Swift 4.2中并受到luca的启发

extension UIBarButtonItem {

    var frame:CGRect?{
        return (value(forKey: "view") as? UIView)?.frame
    }

}


guard let frame = self.navigationItem.rightBarButtonItems?.first?.frame else{ return }

答案 13 :(得分:0)

您可以通过使用NavigationBar上的layoutMarginsframe之类的属性进行粗略计算,并结合Human Interface Guidelines中的图标尺寸指南,并考虑当前设备的方向:

- (CGRect)rightBarButtonFrame {
    CGFloat imageWidth = 28.0;
    CGFloat imageHeight = UIDevice.currentDevice.orientation == UIDeviceOrientationLandscapeLeft || UIDevice.currentDevice.orientation == UIDeviceOrientationLandscapeRight ? 18.0 : 28.0;
    UIEdgeInsets navigationBarLayoutMargins = self.navigationController.navigationBar.layoutMargins;
    CGRect navigationBarFrame = self.navigationController.navigationBar.frame;
    return CGRectMake(navigationBarFrame.size.width-(navigationBarLayoutMargins.right + imageWidth), navigationBarFrame.origin.y + navigationBarLayoutMargins.top, imageWidth, imageHeight);
}

答案 14 :(得分:0)

快速4 向上当前的最佳方法是从以下位置访问其框架:

self.navigationItem.rightBarButtonItems

let customView = navigationItem.rightBarButtonItems?.first?.customView // access the first added customView

以这种方式访问​​比访问私有api安全。

  • 在此查看答案:

After Add a CustomView to navigationItem, CustomView always return nil

答案 15 :(得分:0)

我在条形按钮项上使用了一个视图,并在视图上使用了标签:

for view in bottomToolbar.subviews {
   if let stackView = view.subviews.filter({$0 is UIStackView}).first {
       //target view has tag = 88
       if let targetView = stackView.subviews.filter({$0.viewWithTag(88) != nil}).first {                                
          //do something with target view
   }
}

}