it-swarm.com.ru

UIBarButtonItem: Как я могу найти его кадр?

У меня есть кнопка на панели инструментов. Как я могу взять его кадр? У UIBarButtonItems нет свойства frame?

60
totalitarian

Попробуй это;

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

Этот способ лучше всего подходит для меня:

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

Спасибо Anoop Vaidya за предложенный ответ. Альтернативой может быть (при условии, что вы знаете положение кнопки на панели инструментов)

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


CGRect viewframe = view.frame;
12
totalitarian

С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            
}
8
Luca Davanzo

Слишком много грубых ответов в этой теме. Вот правильный способ сделать это:

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
Dan Stenmark
-(CGRect) getBarItemRc :(UIBarButtonItem *)item{
    UIView *view = [item valueForKey:@"view"];
    return [view frame];
}
2
Gank

Вот то, что я использую в 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...
}
2
jday

Попробуйте эту реализацию:

@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
1
Werner Altewischer

Вот правильный способ сделать это:

-(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;
}
1
Muhammad Naeem Paracha

в 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 }
0
Reimond Hill

Вы должны выполнить цикл по подпредставлениям и проверить их тип или их содержание на предмет идентификации ..... Kvo не является безопасным для доступа к представлению, и вы не можете быть уверены в индексе.

0
user4091416

Вы можете приблизительно рассчитать его, используя такие свойства, как layoutMargins и frame на панели навигации, в сочетании с руководствами по размерам значков из Рекомендации по интерфейсу пользователя и учитывать текущую ориентацию устройства:

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

Вы можете создать UIBarButtonItem с пользовательским представлением, которое является UIButton, тогда вы можете делать все, что захотите. :]

0
Nix Wang

Проверьте этот ответ: Как применить границы и радиус угла к UIBarButtonItem? который объясняет, как перебирать подпредставления, чтобы найти кадр кнопки.

0
frandogger