【发布时间】:2012-01-04 03:04:27
【问题描述】:
在 UIToolbar 中确定 UIBarButtonItem 的 x,y 位置的最简单方法是什么?
我找到的唯一答案是any way to know where uibarbuttonitem has been drawn。
所有建议的答案似乎都太复杂了。应该有一种更简单的方法来获取该死的 UIBarButtonItem 的位置不存在吗?
【问题讨论】:
标签: ios uibarbuttonitem uitoolbar
在 UIToolbar 中确定 UIBarButtonItem 的 x,y 位置的最简单方法是什么?
我找到的唯一答案是any way to know where uibarbuttonitem has been drawn。
所有建议的答案似乎都太复杂了。应该有一种更简单的方法来获取该死的 UIBarButtonItem 的位置不存在吗?
【问题讨论】:
标签: ios uibarbuttonitem uitoolbar
不幸的是,没有简单的方法可以确定 UIBarButtonItem 的位置。 UIBarButtonItem 本质上是一个 NSObject,它只做两件事:描述工具栏按钮的外观和感觉,并将事件转发到指定的目标/动作选择器。
现在,鉴于所有按钮都是 UIToolbar 的子视图,并且所有按钮事件都通过它们各自的 UIBarButtonItems 进行路由,因此循环遍历 UIToolbar 的所有子视图并且当您找到目标是 UIBarButtonItem 的按钮时,这是非常简单的,只需获取该按钮的框架。一些代码:
UIToolbar *toolbar = <your toolbar>;
UIBarButtonItem *barButtonItem = <your item>;
UIButton *button = nil;
for (UIView *subview in toolbar.subviews) {
if ([subview isKindOfClass:[UIButton class]]) {
for (id target in [(UIButton *)subview allTargets]) {
if (target == barButtonItem) {
button = (UIButton *)subview;
break;
}
}
if (button != nil) break;
}
}
CGRect frame = button.frame;
【讨论】:
UIToolbar *toolbar;
for (UIView *v in [toolbar items])
{
if ([v isKindOfClass:[UIBarButtonItem class]])
{
UIBarButtonItem *b = (UIBarButtonItem*)v;
//do something with b..
}
}
【讨论】:
我用这个似乎是最优雅的方式
- (CGRect)frameForBarButtonItem:(UIBarButtonItem *)buttonItem
{
UIView *view = [buttonItem valueForKey:@"view"];
return view ? view.frame : CGRectZero;
}
【讨论】:
当使用 UIBarButtonItems 中的弹出框时,这对我有用。
- (void)buttonClicked:(id)sender{
{
CGRect buttonRect = [[sender view] frame];
}
【讨论】:
我使用 johosher 的方法通过 Swift 获取 UIBarButtonItem 的位置。
由于我需要将位置作为 popoverPresentationController 的 sourceRect,因此我必须将其转换为 self.view。我不确定这是否是一个好的解决方案,但效果很好,并且弹出框显示在 UIBarButtonItem 的右侧。
let senderRect = sender.view!!.convertRect(sender.view!!.bounds, toView: self.view)
// additional code for the popover controller
alertController.modalPresentationStyle = UIModalPresentationStyle.Popover
alertController.popoverPresentationController?.sourceRect = senderRect
alertController.popoverPresentationController?.sourceView = self.view
【讨论】:
更“迅速”的 SWIFT 方式:
func userAction(sender: AnyObject) {
if let originView = sender.valueForKey("view") {
let frame = originView.frame //it's a UIBarButtonItem
} else {
let frame = sender.frame //it's a regular UIButton
}
}
UIBarButtonItem 不是 UIView 的子类,尽管它本质上是一个按钮。去图吧。
【讨论】:
对于 iOS 11(或更高版本)调用:
if let view = barButtonItemView.value(forKey: "view") as? UIView {
let viewFrame = view.frame
}
将返回视图的零点原点。为了解决这个问题,请使用以下命令获取视图的窗口坐标:
let actualPointOnWindow = view.convert(view.frame.origin, to: nil)
如果您的工具栏有任何翻译,请从计算点中减去它们以找到其在工具栏上的位置。
完整代码:
if let view = barButtonItemView.value(forKey: "view") as? UIView {
let viewFrame = view.frame
let actualPointOnWindow = view.convert(view.frame.origin, to: nil)
}
【讨论】: