Objective c 在单个Uitabritem上处理长按

Objective c 在单个Uitabritem上处理长按,objective-c,uigesturerecognizer,uitabbar,uilongpressgesturerecogni,Objective C,Uigesturerecognizer,Uitabbar,Uilongpressgesturerecogni,我在选项卡栏上使用长按手势。但我只需要长按一个特定的选项卡栏项目的手势 我怎样才能解决这个问题?我可以自定义选项卡栏中的长按手势吗?您可以子类化UIAbbarController,并在其选项卡栏中添加UILongPressGestureRecognitor。作为手势识别器的代表,当它检测到长按时,您可以选择。由于选项卡栏项目将在用户触摸后立即被选中,因此可以使用selectedItem属性执行此检查 @interface TabBarController () <UIGestureReco

我在选项卡栏上使用长按手势。但我只需要长按一个特定的选项卡栏项目的手势


我怎样才能解决这个问题?我可以自定义选项卡栏中的长按手势吗?

您可以子类化
UIAbbarController
,并在其
选项卡栏中添加
UILongPressGestureRecognitor
。作为手势识别器的代表,当它检测到长按时,您可以选择。由于选项卡栏项目将在用户触摸后立即被选中,因此可以使用
selectedItem
属性执行此检查

@interface TabBarController () <UIGestureRecognizerDelegate>
@property (nonatomic, strong) UILongPressGestureRecognizer *longPressRecognizer;

@end

@implementation TabBarController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(recognizerFired:)];
    self.longPressRecognizer.delegate = self;
    [self.tabBar addGestureRecognizer:self.longPressRecognizer];
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {

    // This will ensure the long press only occurs for the
    // tab bar item which has it's tag set to 1.
    // You can set this in Interface Builder or in code
    // wherever you are creating your tabs.
    if (self.tabBar.selectedItem.tag == 1) {
        return YES;
    }
    else {
        return NO;
    }

}

- (void)recognizerFired:(UILongPressGestureRecognizer *)recognizer {
    // Handle the long press...
}

@end
@接口选项卡控制器()
@属性(非原子,强)UILongPressGestureRecognitor*LongPressRecognitor;
@结束
@TabBarController的实现
-(无效)viewDidLoad{
[超级视图下载];
self.longPressRecognizer=[[uilongpressgesturecognizer alloc]initWithTarget:self-action:@selector(recognizerfiled:)];
self.longpress recognizer.delegate=self;
[self.tabBar addgesturecognizer:self.longPressRecognizer];
}
-(BOOL)手势识别器应开始:(UIGestureRecognizer*)手势识别器{
//这将确保长时间按压仅发生在
//标签设置为1的选项卡栏项。
//您可以在Interface Builder或代码中进行设置
//无论您在何处创建选项卡。
if(self.tabBar.selectedItem.tag==1){
返回YES;
}
否则{
返回否;
}
}
-(void)识别器已激发:(uiLongPressGestureRecognitor*)识别器{
//处理长时间的压力。。。
}
@结束

如果您只需要识别其中一个选项卡项上的长按,可以在相应的viewController的
viewDidLoad
方法中执行此操作:

UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget: self action: @selector(handleLongPress:)];
[self.tabBarController.tabBar addGestureRecognizer: longPressGesture];
然后:

- (void)handleLongPress:(UILongPressGestureRecognizer *) recognizer {
    if (recognizer.state == UIGestureRecognizerStateBegan) {

        UITabBar *tabBar = ((UITabBar* )recognizer.view);

        if (tabBar.selectedItem == self.tabBarItem) {
            doSomethingVeryExciting();
        }
    }
}

如果您只是切换选项卡,则不会触发此操作。

以下是我使用Swift 3的方法:

protocol MyTabControllerProtocol: class {
    func tabLongPressed()
}

class MyTabController: UITabBarController {
    func viewDidLoad() {
        super.viewDidLoad()

        viewControllers = [
            // add your view controllers for each tab bar item
            // NOTE: if you want view controller to respond to long press, then it should extend MyTabControllerProtocol
        ]

        let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(astroButtonItemLongPressed(_:)))
        tabBar.addGestureRecognizer(longPressRecognizer)
    }

    func astroButtonItemLongPressed(_ recognizer: UILongPressGestureRecognizer) {
        guard recognizer.state == .began else { return }
        guard let tabBar = recognizer.view as? UITabBar else { return }
        guard let tabBarItems = tabBar.items else { return }
        guard let viewControllers = viewControllers else { return }
        guard tabBarItems.count == viewControllers.count else { return }

        let loc = recognizer.location(in: tabBar)

        for (index, item) in tabBarItems.enumerated() {
            guard let view = item.value(forKey: "view") as? UIView else { continue }
            guard view.frame.contains(loc) else { continue }

            if let nc = viewControllers[index] as? UINavigationController {
                if let vc = nc.viewControllers.first as? MyTabControllerProtocol {
                    vc.tabLongPressed()
                }
            } else if let vc = viewControllers[index] as? MyTabControllerProtocol {
                vc.tabLongPressed()
            }

            break
        }
    }
}

我通过获取特定tabBarItem的用户可以交互的视图来实现这一点,并简单地添加了长按手势。通过这种方式,您不必编写任何协议或TabBarViewController的子类

let longPressGestureRecognizer = UILongPressGestureRecognizer.init(target: self, action: #selector(longTap(_:)))
    longPressGestureRecognizer.minimumPressDuration = 1.0
    self.tabBarController?.orderedTabBarItemViews()[0].addGestureRecognizer(longPressGestureRecognizer)
至于获取tabbarItemView:

extension UITabBarController {
func orderedTabBarItemViews() -> [UIView] {
    let interactionViews = tabBar.subviews.filter({$0.isUserInteractionEnabled})
    return interactionViews.sorted(by: {$0.frame.minX < $1.frame.minX})
}
扩展控制器{
func orderedTabBarItemViews()->[UIView]{
让interactionViews=tabBar.subviews.filter({$0.isUserInteractionEnabled})
返回interactionViews.sorted(按:{$0.frame.minX<$1.frame.minX})
}

备注:viewController,即“self”是tabBarController的第一项。

以下是swift 5中的解决方案: 使用情节提要或代码将longpress手势识别器添加到“整个”选项卡栏。。 别忘了让ViewController成为它的委托..并实现下面的委托方法 要检查传入的触摸是否在选项卡栏子视图的“一”内,请执行以下操作。如果是,则返回true,否则返回false。。 以下是仅当我们长按第一个选项卡时才允许识别器启动的代码:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {

    if touch.view?.isDescendant(of: tabBar.subviews[1]) == true {return true}
    return false



}

注意:tabbar.subviews数组计数是项目数+1,这是tabbar的背景。所以,若您想查看第一个项目,您可以找到它,索引1而不是0

请共享您的代码或IB。我的代码不正确。是否可以识别长按TabBarItem而不切换tab?若用户选择firs怎么办t item然后点击并按住任何其他项目,它仍然可以工作,这并不酷。因为第一个项目仍然会被选中!@AkhilKC从
UITabBarControllerDelegate
查看
shoulldselect
方法谢谢,这是最好的答案。