J'ai un bouton dans une barre d'outils. Comment puis-je saisir son cadre? UIBarButtonItem
s n'a-t-il pas une propriété frame
?
Essaye celui-là;
UIBarButtonItem *item = ... ;
UIView *view = [item valueForKey:@"view"];
CGFloat width;
if(view){
width=[view frame].size.width;
}
else{
width=(CGFloat)0.0 ;
}
Cette façon fonctionne le mieux pour moi:
UIView *targetView = (UIView *)[yourBarButton performSelector:@selector(view)];
CGRect rect = targetView.frame;
Merci à Anoop Vaidya pour la réponse suggérée. Une alternative pourrait être (à condition de connaître la position du bouton dans la barre d’outils)
UIView *view= (UIView *)[self.toolbar.subviews objectAtIndex:0]; // 0 for the first item
CGRect viewframe = view.frame;
AvecSwift, si vous devez souvent utiliser des éléments de bouton de barre, vous devez implémenter une extension comme celle-ci:
extension UIBarButtonItem {
var frame: CGRect? {
guard let view = self.value(forKey: "view") as? UIView else {
return nil
}
return view.frame
}
}
Ensuite, dans votre code, vous pouvez accéder facilement:
if let frame = self.navigationItem.rightBarButtonItems?.first?.frame {
// do whatever with frame
}
Oof, beaucoup de réponses brutes dans ce fil. Voici la bonne façon de le faire:
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))
}
}
-(CGRect) getBarItemRc :(UIBarButtonItem *)item{
UIView *view = [item valueForKey:@"view"];
return [view frame];
}
Voici ce que j'utilise dans iOS 11 et Swift 4. Cela pourrait être un peu plus propre sans l'option mais je joue la sécurité:
extension UIBarButtonItem {
var view: UIView? {
return perform(#selector(getter: UIViewController.view)).takeRetainedValue() as? UIView
}
}
Et utilisation:
if let barButtonFrame = myBarButtonItem.view?.frame {
// etc...
}
Essayez cette implémentation:
@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
Voici la bonne façon de le faire:
-(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;
}
dans Swift 4.2 et inspiré par luca
extension UIBarButtonItem {
var frame:CGRect?{
return (value(forKey: "view") as? UIView)?.frame
}
}
guard let frame = self.navigationItem.rightBarButtonItems?.first?.frame else{ return }
Vous devez faire une boucle sur les sous-vues et vérifier leur type ou leur contenu afin d'identifier .. Il n'est pas sûr d'accéder à view by kvo et vous ne pouvez pas être sûr de l'index.
Vous pouvez le calculer approximativement à l'aide des propriétés telles que layoutMargins
et frame
sur la barre de navigation, combinées aux guides de taille d'icône de Human Interface Guidelines et prendre en compte l'orientation actuelle du périphérique:
- (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);
}
Vous pouvez créer un UIBarButtonItem avec une vue personnalisée, qui est un UIButton, puis vous pouvez faire ce que vous voulez. :]
Regardez cette réponse: Comment appliquer des bordures et des rayons de coins à UIBarButtonItem? qui explique comment passer en revue les vues secondaires pour trouver le cadre d'un bouton.