在点击背景时关闭UIPickerView [英] Dismissing UIPickerView on tapping background

查看:58
本文介绍了在点击背景时关闭UIPickerView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要添加一个uipickerview作为主视图的子视图.为了在点击背景视图时关闭pickerview,我在主视图中添加了一个UITapGestureRecognizer.

我正在使用以下代码为主视图添加GestureRecognizer

  UITapGestureRecognizer * gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap :)];gestureRecognizer.numberOfTapsRequired = 1;gestureRecognizer.numberOfTouchesRequired = 1;poseRecognizer.delegate =自我;[self.view addGestureRecognizer:gestureRecognizer];[gestureRecognizer发布]; 

在handleSingleTap方法中,我关闭了pickerview.

但是问题是,当我在pickerview内部点击时,还会调用handleSingleTap.为了避免这种情况,我使用了UIGestureRecognizer的以下委托方法

 -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer应该ReceiveTouch:(UITouch *)touch {/**如果点击位于按钮内,则返回NO,以确保检测到按钮点击.*/如果([touch.view isKindOfClass:[UIButton类]]){返回FALSE;}否则if([touch.view isKindOfClass:[UIPickerView类]]){返回FALSE;}返回TRUE;} 

它适用于按钮,但不适用于 UIPickerView .有人可以帮我吗?

解决方案

我已经为您的特定要求编写了解决方案.

首先,我按照您描述的方式实现了代码,并观察到与您报告的问题相同的问题-当您轻按任何内容(包括UIButton)时,会将虚假的轻击事件发送到轻击处理程序.

这告诉我UITapGestureRecogniser正在窃取" UIButton应有的接触,因此我决定最简单,最实用的解决方案是利用该功能,以达到我的优势,因此我将UITapGestureRecogniser分配给了两者.pickerview和按钮也.我们只舍弃了pickerview的水龙头,我们解析了其他水龙头,并将其传递给按钮的水龙头处理程序.

注意-为了方便起见,我在xib中分配了pickerview的数据源和委托.您还需要这样做,或者在代码中进行设置.

标题

 ////ViewController.h//stackExchangeDemo////由在18/01/12上未同步创建.//通过http://stackoverflow.com/a/8908028/830899发布到公共领域//#import< UIKit/UIKit.h>@interface ViewController:UIViewController< UIPickerViewDelegate,UIPickerViewDataSource>{UIButton * btn1;UIPickerView * picker1;}@属性(保留,非原子)IBOutlet UIButton * btn1;@属性(保留,非原子)IBOutlet UIPickerView * picker1;@结尾 

实施

 ////ViewController.m//stackExchangeDemo////由在18/01/12上未同步创建.//通过http://stackoverflow.com/a/8908028/830899发布到公共领域//#import"ViewController.h"@implementation ViewController@synthesize btn1;@synthesize picker1;-(void)didReceiveMemoryWarning{[super didReceiveMemoryWarning];//释放所有未使用的缓存数据,图像等.}#pragma mark-查看生命周期-(void)handleSingleTap:(UITapGestureRecognizer *)tapper {如果(tapper.state == UIGestureRecognizerStateEnded){NSLog(@%@",NSStringFromSelector(_cmd));}}-(IBAction)handleButtonTap:(id)sender {NSLog(@%@",NSStringFromSelector(_cmd));}-(void)handleButtonTapGesture:(UITapGestureRecognizer *)tapper {//调用按钮事件处理程序UIControlEvents eventsToHandle = UIControlEventTouchUpInside;如果(tapper.state == UIGestureRecognizerStateEnded){UIButton * btn =(UIButton *)tapper.view;for([btn actionsForTarget:self forControlEvent:eventsToHandle]中的NSString * selName){SEL动作= NSSelectorFromString(selName);如果(操作){[self performSelector:action withObject:btn1];休息;}};}}-(void)handleDummyTap:(UITapGestureRecognizer *)tapper {//静默忽略此视图的tap事件.}-(void)setupTap:(UIView *)查看动作:(SEL)动作{//为给定视图分配自定义点击事件处理程序.UITapGestureRecognizer * gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:action];[查看addGestureRecognizer:gestureRecognizer];[gestureRecognizer发布];}-(void)viewDidLoad{[super viewDidLoad];//加载视图后进行其他任何设置,通常是从笔尖进行.[self setupTap:self.view操作:@selector(handleSingleTap :)];[self setupTap:picker1操作:@selector(handleDummyTap :)];[self setupTap:btn1操作:@selector(handleButtonTapGesture :)];}-(void)viewDidUnload{[self setBtn1:nil];[self setPicker1:nil];[super viewDidUnload];//释放主视图的所有保留子视图.//例如self.myOutlet = nil;}-(void)viewWillAppear:(BOOL)动画{[super viewWillAppear:animated];}-(void)viewDidAppear:(BOOL)动画{[super viewDidAppear:animated];}-(void)viewWillDisappear:(BOOL)动画{[super viewWillDisappear:animated];}-(void)viewDidDisappear:(BOOL)动画{[super viewDidDisappear:animated];}-(BOOL)应该AutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{//对于支持的方向返回YES返回(interfaceOrientation!= UIInterfaceOrientationPortraitUpsideDown);}#pragma mark @protocol UIPickerViewDataSource< NSObject>//返回要显示的列"数.-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {返回1;}//返回每个组件中的行数.-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {返回1;}#pragma mark @protocol UIPickerViewDelegate< NSObject>-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {返回[@这么久,感谢所有的鱼".复制autorelease];}-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {NSLog(@%@",NSStringFromSelector(_cmd));}-(void)dealloc {[btn1发布];[picker1版本];[super dealloc];}@结尾 

I am adding a uipickerview as the subview of the main view. To dismiss the pickerview on tapping the backgroud view, i am adding a UITapGestureRecognizer to the main view.

I am using the following code to add the GestureRecognizer for main view

 UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
    gestureRecognizer.numberOfTapsRequired=1;
    gestureRecognizer.numberOfTouchesRequired=1;
    gestureRecognizer.delegate = self;
    [self.view addGestureRecognizer:gestureRecognizer];
    [gestureRecognizer release];

In the handleSingleTap method i am dismissing the pickerview.

But the problem is handleSingleTap is also called when I tap inside the pickerview. To avoid it i used the following delegate method of UIGestureRecognizer

 -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {

    /*
     *If the tap is inside a button return NO, to ensure the button click is detected.
     */
    if ([touch.view isKindOfClass:[UIButton class]]){
        return FALSE;
    }else if([touch.view isKindOfClass:[UIPickerView class]]) {

        return FALSE;

    }
    return TRUE;
}

It is working for button,But is not working for UIPickerView. Can anyone help me with this?

解决方案

I have coded up a solution to your particular requirement.

first, i implemented your code as you have described and observed the same problem you reported - spurious tap events being sent to tap handler, when you tapped on anything, including a UIButton.

this told me that the UITapGestureRecogniser was "stealing" the touches that should have gone to the UIButton, so i decided the simplest, most pragmatic solution was to use that feature to my advantage, and so i assigned a UITapGestureRecogniser to both the pickerview and the button also. the taps for the pickerview we just discard, the others we parse and pass on to the button's tap handler.

note - for expedience i assigned the pickerview's datasource and delegate in the xib. you will need to do that also, or set it in code.

header

//
//  ViewController.h
//  stackExchangeDemo
//
//  Created by unsynchronized on 18/01/12.
//  released to public domain via http://stackoverflow.com/a/8908028/830899
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController 
<UIPickerViewDelegate, UIPickerViewDataSource>

{
   UIButton *btn1; 
   UIPickerView *picker1;
}

@property (retain, nonatomic) IBOutlet UIButton *btn1;
@property (retain, nonatomic) IBOutlet UIPickerView *picker1;

@end

implementation

//
//  ViewController.m
//  stackExchangeDemo
//
//  Created by unsynchronized on 18/01/12.
//  released to public domain via http://stackoverflow.com/a/8908028/830899
//

#import "ViewController.h"

@implementation ViewController
@synthesize btn1;
@synthesize picker1;

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

-(void) handleSingleTap:(UITapGestureRecognizer *) tapper {

    if (tapper.state == UIGestureRecognizerStateEnded) {
        NSLog(@"%@",NSStringFromSelector(_cmd));
    }

}

- (IBAction)handleButtonTap:(id)sender {
    NSLog(@"%@",NSStringFromSelector(_cmd));
}


-(void) handleButtonTapGesture:(UITapGestureRecognizer *) tapper {
    // call the buttons event handler

    UIControlEvents eventsToHandle = UIControlEventTouchUpInside;

    if (tapper.state == UIGestureRecognizerStateEnded) {
        UIButton *btn = (UIButton *) tapper.view;

        for (NSString *selName in [btn  actionsForTarget:self forControlEvent:eventsToHandle]) {

            SEL action = NSSelectorFromString(selName);
            if (action) {

                [self  performSelector:action withObject:btn1];
                break;
            }

        };  


    }

}

-(void) handleDummyTap:(UITapGestureRecognizer *) tapper {
    // silently ignore the tap event for this view.
}

-(void) setupTap:(UIView *) view action:(SEL)action {
    // assign custom tap event handler for given view.
    UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:action];
    [view addGestureRecognizer:gestureRecognizer];
    [gestureRecognizer release];    
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self setupTap:self.view action:@selector(handleSingleTap:)];
    [self setupTap:picker1 action:@selector(handleDummyTap:)];
    [self setupTap:btn1 action:@selector(handleButtonTapGesture:)];



}



- (void)viewDidUnload
{
    [self setBtn1:nil];
    [self setPicker1:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}


#pragma mark @protocol UIPickerViewDataSource<NSObject>

// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
    return 1;
}

// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {

    return 1;
}


#pragma mark @protocol UIPickerViewDelegate<NSObject>
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    return [@"so long and thanks for all the fish".copy autorelease ];
}


- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
    NSLog(@"%@",NSStringFromSelector(_cmd));

}

- (void)dealloc {
    [btn1 release];
    [picker1 release];
    [super dealloc];
}
@end

这篇关于在点击背景时关闭UIPickerView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆