Ios UINavigationBar触摸屏
当用户点击我的一个视图的导航栏标题时,我想在touch上触发一个事件 我有点不知所措,不知道我是否可以访问UINavigationBar标题的视图,以便将触摸事件连接到它Ios UINavigationBar触摸屏,ios,iphone,cocoa-touch,uikit,uinavigationbar,Ios,Iphone,Cocoa Touch,Uikit,Uinavigationbar,当用户点击我的一个视图的导航栏标题时,我想在touch上触发一个事件 我有点不知所措,不知道我是否可以访问UINavigationBar标题的视图,以便将触摸事件连接到它 这可能吗?类引用的UINavigationItem有一个属性,您可以将其设置为自定义的UIView 换句话说,用触摸处理程序创建UIView的子类,然后当你按下导航项时,将该项的titleView属性设置为子类的一个实例。我找到的解决方案是一个按钮,我使用以下方法(但我不知道它是否“合法”): 把这段代码放在你设置标题的地方。
这可能吗?类引用的
UINavigationItem
有一个属性,您可以将其设置为自定义的UIView
换句话说,用触摸处理程序创建
UIView
的子类,然后当你按下导航项时,将该项的titleView
属性设置为子类的一个实例。我找到的解决方案是一个按钮,我使用以下方法(但我不知道它是否“合法”):
把这段代码放在你设置标题的地方。然后在其他地方,我要测试:
- (IBAction)didTapTitleView:(id) sender
{
NSLog(@"Title tap");
}
在控制台上记录了哪个“标题点击”
我这样做可能是完全错误的,但可能会给你一个想法,你可以看看。这确实帮了我的忙!不过,可能还有更好的方法。您可以添加一个手势识别器,只需轻触导航控制器的标题即可。 我发现在navigationBar子视图中,标题是索引1处的标题,左按钮的索引是0,右按钮的索引是2
UITapGestureRecognizer *navSingleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(navSingleTap)];
navSingleTap.numberOfTapsRequired = 1;
[[self.navigationController.navigationBar.subviews objectAtIndex:1] setUserInteractionEnabled:YES];
[[self.navigationController.navigationBar.subviews objectAtIndex:1] addGestureRecognizer:navSingleTap];
然后在实现中的某个地方实现以下内容
-(void)navSingleTap
所以你可以用它来点击一次,或者你可以在标题上实现任何你想要的手势识别器。其他答案都不适合我。我没有向导航栏的现有子视图添加手势,也没有替换标题视图,而是添加了一个清晰的UIView,覆盖了导航栏的大部分
- (void) setupNavbarGestureRecognizer {
// recognise taps on navigation bar to hide
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showHideNavbar)];
gestureRecognizer.numberOfTapsRequired = 1;
// create a view which covers most of the tap bar to
// manage the gestures - if we use the navigation bar
// it interferes with the nav buttons
CGRect frame = CGRectMake(self.view.frame.size.width/4, 0, self.view.frame.size.width/2, 44);
UIView *navBarTapView = [[UIView alloc] initWithFrame:frame];
[self.navigationController.navigationBar addSubview:navBarTapView];
navBarTapView.backgroundColor = [UIColor clearColor];
[navBarTapView setUserInteractionEnabled:YES];
[navBarTapView addGestureRecognizer:gestureRecognizer];
}
我不想将按钮指定为自定义标题视图,因为这意味着我不能再使用标准标题。另一方面,在向导航栏添加点击手势识别器时,我们必须确保在点击栏按钮时不会触发该识别器 此解决方案实现了这两个功能(添加到
UINavigationBar
子类):
注意:我们正在使用未记录的
-valueForKey:@“titleView”
检索标题视图。从技术上讲,它不使用私有API,但在未来的iOS版本中仍可能失败可能的选项之一:(使用UILabel)
这可以通过将
UITapGestureRecognitor
附加到与标题视图相对应的导航栏子视图来实现
由于titleView的索引因栏按钮项的数量而异,因此有必要遍历所有导航栏子视图以找到正确的视图
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
addTitleViewTapAction("tapped", numberOfTapsRequired: 3)
}
func addTitleViewTapAction(action: Selector, numberOfTapsRequired: Int) {
if let subviews = self.navigationController?.navigationBar.subviews {
for subview in subviews {
// the label title is a subview of UINavigationItemView
if let _ = subview.subviews.first as? UILabel {
let gesture = UITapGestureRecognizer(target: self, action: action)
gesture.numberOfTapsRequired = numberOfTapsRequired
subview.userInteractionEnabled = true
subview.addGestureRecognizer(gesture)
break
}
}
}
}
@objc func tapped() {
print("secret tap")
}
}
这是Swift中最简单、最简单的解决方案,只需复制/粘贴并填写以下空白:
let navTapGesture = UITapGestureRecognizer(target: <#T##AnyObject?#>, action: <#T##Selector#>)
navigationItem.titleView.userInteractionEnabled = true
navigationItem.titleView.addGestureRecognizer(navTapGesture)
让NavTap手势=UITapGestureRecognitizer(目标:,操作:)
navigationItem.titleView.userInteractionEnabled=true
navigationItem.titleView.AddGestureRecognitor(导航手势)
请确保在标题视图
上将userInteractionEnabled
设置为true
,默认情况下将其关闭。基于此,我采用了下面的“功能性”方法,我不确定它是否可读,但我更喜欢它而不是打破循环
if let navTitle = self.navigationController?.navigationBar.subviews.first(where: {$0.subviews.first is UILabel}) {
let gesture = UITapGestureRecognizer(target: self, action: action)
gesture.numberOfTapsRequired = numberOfTapsRequired
navTitle.isUserInteractionEnabled = true
navTitle.addGestureRecognizer(gesture)
}
谢谢,但是我该如何处理这个触摸,例如-如果触摸了标题视图,我如何在我的全局视图控制器中调用一个方法?同样,使用这种方法,我的标题属性丢失。你能进一步解释一下吗?我添加了一个带有简单NSLog(@“touch”)的touchesbreated处理程序;但是当标题视图被点击时,它什么也不做。我正在创建子类的一个实例,并将其分配给我要推送的视图的实例,即view.navigationItem.titleView=mySubclass;自定义
UIView
可以有许多属性,包括替换标题的UILabel
,以及创建自定义视图实例时设置的“父”视图控制器的UIViewController
属性。还要检查您的视图是否有足够大的框架。虽然它的标题方向正确,但这非常难看-UIButton的字体属性已被弃用,即使使用该属性,标题文本看起来也与正常的非常不同。为什么要用按钮呢?一个清晰的UIView会更好。使用UILabel没有错。只需确保您设置了label.userInteractionEnabled=YES。如果没有,标签将不会对触摸事件做出反应。这是迄今为止唯一一个对我有效的标签,尽管我似乎需要添加:[self.navigationController.navigationBar setUserInteractionEnabled:YES];在我的应用程序的其余部分中,由于按钮名称可变,我仍然会对按钮产生干扰-有一种一致的方式,只是将可触摸性附加到标题(在我的例子中是UIImageView)aha,我终于得到了一个标题“可触摸”——下面是如何做到的:@SamJoseph你应该将该解决方案发布为答案这一个很好,因为它不会弄乱像“后退”按钮这样的东西。如果你不想设置自定义标题视图,这一点很有效。(我没有)是否可以设置一个色调,使它看起来更像一个按钮?我试过setTintColor
和setTintAdjustmentMode
,但两种方法都不起作用。这显然是最有效的答案。谢谢~我发现如果我深入到故事板并返回,我必须将它放入viewDidLoad
方法才能使它工作,否则我所有的导航栏项目都会在那之后激活它。嗨~@phmagic,我喜欢它只对topViewController有效,而不是对secondViewController有效。你知道为什么吗?有人面临同样的问题吗?这个答案对我很有用,它覆盖了UINavigationBar上某个类别中的-[gestureRecognitzerShouldBegin]
,并将该类别导入到我的视图控制器中。
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doSomething:)];
UILabel * titleView = [UILabel new];
titleView.text = @"Test";
[titleView sizeToFit];
titleView.userInteractionEnabled = YES;
[titleView addGestureRecognizer:tapGesture];
self.navigationItem.titleView = titleView;
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
addTitleViewTapAction("tapped", numberOfTapsRequired: 3)
}
func addTitleViewTapAction(action: Selector, numberOfTapsRequired: Int) {
if let subviews = self.navigationController?.navigationBar.subviews {
for subview in subviews {
// the label title is a subview of UINavigationItemView
if let _ = subview.subviews.first as? UILabel {
let gesture = UITapGestureRecognizer(target: self, action: action)
gesture.numberOfTapsRequired = numberOfTapsRequired
subview.userInteractionEnabled = true
subview.addGestureRecognizer(gesture)
break
}
}
}
}
@objc func tapped() {
print("secret tap")
}
}
let navTapGesture = UITapGestureRecognizer(target: <#T##AnyObject?#>, action: <#T##Selector#>)
navigationItem.titleView.userInteractionEnabled = true
navigationItem.titleView.addGestureRecognizer(navTapGesture)
if let navTitle = self.navigationController?.navigationBar.subviews.first(where: {$0.subviews.first is UILabel}) {
let gesture = UITapGestureRecognizer(target: self, action: action)
gesture.numberOfTapsRequired = numberOfTapsRequired
navTitle.isUserInteractionEnabled = true
navTitle.addGestureRecognizer(gesture)
}