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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14318368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:51:00  来源:igfitidea点击:

UIBarButtonItem: How can I find its frame?

iosobjective-cswift

提问by totalitarian

I have a button in a toolbar. How can I grab its frame? Do UIBarButtonItems not have a frameproperty?

我在工具栏中有一个按钮。我怎样才能抓住它的框架?做UIBarButtonItem不是有一个frame属性?

回答by Anoop Vaidya

Try this one;

试试这个;

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

回答by MobileMon

This way works best for me:

这种方式最适合我:

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

回答by totalitarian

Thanks to Anoop Vaidya for the suggested answer. An alternative could be (providing you know the position of the button in the toolbar)

感谢 Anoop Vaidya 提供建议的答案。另一种可能是(前提是您知道工具栏中按钮的位置)

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


CGRect viewframe = view.frame;

回答by Luca Davanzo

With Swift, if you needs to often work with bar button items, you should implement an extension like this:

使用Swift,如果您需要经常使用条形按钮项目,您应该实现这样的扩展:

extension UIBarButtonItem {

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

}

Then in your code you can access easily:

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

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

回答by Dan Stenmark

Oof, lots of rough answers in this thread. Here's the right way to do it:

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))
    }
}

回答by jday

Here's what I'm using in iOS 11 & Swift 4. It could be a little cleaner without the optional but I'm playing it safe:

这是我在 iOS 11 和 Swift 4 中使用的。没有可选的它可能会更干净一些,但我很安全:

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

And usage:

和用法:

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

回答by Gank

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

回答by Werner Altewischer

Try this implementation:

试试这个实现:

@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

回答by turingtested

You can roughly calculate it by using properties like layoutMarginsand frameon the navigationBar, combined with icon size guides from Human Interface Guidelinesand take into count the current device orientation:

您可以使用导航栏上的layoutMarginsframe等属性粗略计算它,结合人机界面指南中的图标大小指南,并考虑当前设备方向:

- (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);
}

回答by vhong

Swift 4up The current best way to do it is to access its frame from :

Swift 4up 当前最好的方法是从以下位置访问其框架:

self.navigationItem.rightBarButtonItemsby

self.navigationItem.rightBarButtonItems经过

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

Accessing this way is safer than accessing private api.

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

  • check out the answer in this :
  • 看看这个答案:

After Add a CustomView to navigationItem, CustomView always return nil

给导航项添加一个CustomView后,CustomView总是返回nil