webentwicklung-frage-antwort-db.com.de

UIBarButtonItem: Wie finde ich seinen Rahmen?

Ich habe eine Schaltfläche in einer Symbolleiste. Wie kann ich seinen Rahmen ergreifen? Verfügt UIBarButtonItems nicht über eine frame-Eigenschaft?

60
totalitarian

Probier diese;

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

Dieser Weg funktioniert am besten für mich:

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

Vielen Dank an Anoop Vaidya für die vorgeschlagene Antwort. Eine Alternative könnte sein (vorausgesetzt, Sie kennen die Position der Schaltfläche in der Symbolleiste)

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


CGRect viewframe = view.frame;
12
totalitarian

Wenn Sie mitSwifthäufig mit Bar-Button-Elementen arbeiten müssen, sollten Sie eine Erweiterung wie diese implementieren:

extension UIBarButtonItem {

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

}

Dann können Sie in Ihrem Code einfach darauf zugreifen:

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

Oof, viele grobe Antworten in diesem Thread. Hier ist der richtige Weg:

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

Hier ist, was ich in iOS 11 und Swift 4 verwende. Es könnte ein bisschen sauberer sein ohne die Option, aber ich gehe auf Nummer sicher

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

Und Verwendung:

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

Versuchen Sie diese Implementierung:

@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

Hier ist der richtige Weg:

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

in Swift 4.2 und luca inspiriert

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

Sie sollten eine Schleife über die Unteransichten durchführen und ihren Typ oder Inhalt auf Identifizierung überprüfen .. Es ist nicht sicher, mit kvo auf view zuzugreifen, und Sie können den Index nicht genau kennen.

0
user4091416

Sie können es grob berechnen, indem Sie Eigenschaften wie layoutMargins und frame in der Navigationsleiste in Kombination mit Symbolgrößenrichtlinien aus Richtlinien für Benutzeroberflächen verwenden und die aktuelle Geräteorientierung berücksichtigen:

- (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

Sie können ein UIBarButtonItem mit einer benutzerdefinierten Ansicht (UIButton) erstellen. Anschließend können Sie machen, was Sie möchten. :]

0
Nix Wang

Sehen Sie sich diese Antwort an: Wie werden Ränder und Eckenradius auf UIBarButtonItem angewendet? Hier erfahren Sie, wie Sie über Subviews blättern, um den Frame einer Schaltfläche zu finden.

0
frandogger