【问题标题】:Dismiss a view when a user taps anywhere outside the view当用户点击视图外的任意位置时关闭视图
【发布时间】:2013-04-16 10:41:31
【问题描述】:

我有一个非常复杂的应用程序,其中包含许多堆叠视图,其中包含许多按钮、绘图区域和其他自定义触摸处理。我正在显示一个可拖动的辅助视图,它可以位于所有其他视图之上。如果用户点击辅助视图之外的任何位置,我需要关闭此视图。我尝试使用多个 UIWindows 并将 Gesture 识别器添加到 UIWindow 。

【问题讨论】:

    标签: ios cocoa-touch uiview


    【解决方案1】:

    一个简单的方法是添加一个透明按钮,其边界等于超级视图的边界。超级视图在您的辅助视图下方插入透明按钮。

    透明按钮添加了一个点击事件,可以关闭辅助视图和它自己的透明按钮。

    例如:

    UIButton *transparencyButton = [[UIButton alloc] initWithFrame:superview.bounds];
    transparencyButton.backgroundColor = [UIColor clearColor];
    [superview insertSubview:transparencyButton belowSubview:helperView];
    [transparencyButton addTarget:self action:@selector(dismissHelper:) forControlEvents:UIControlEventTouchUpInside];
    

    dismissHelper: 方法可以做到这一点:

    - (void)dismissHelper:(UIButton *)sender
    {
        [helperView dismiss];
        sender.hidden = YES;
        // or [sender removeFromSuperview]
    }
    

    【讨论】:

    • 如果我们想与视图交互怎么办?
    【解决方案2】:

    您可以通过触摸并查看触摸的 .view 属性来检查被触摸的视图。它反映了视图实际起源的视图。

    假设您保留对视图的引用(通过 IBOutlet 或其他方式)对名为“myView”的视图的引用,则以下工作正常。

    在您的 .m 文件中。 touchesBegan: 函数在用户每次触碰手指时触发。我们遍历触摸以查看触摸的原始视图是否不等于“myView”。这种比较也可以通过检查您用来识别视图的类、标签或任何其他属性来完成。下面给出示例。

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  {
        NSLog(@"touches began");
        UITouch *touch = [touches anyObject];   
        if(touch.view!=myView){
           myView.hidden = YES;
        }
    }
    

    或者在使用标签的情况下:

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  {
        NSLog(@"touches began");
        UITouch *touch = [touches anyObject];   
        if(touch.view.tag!=23){
           myView.hidden = YES;
        }
    }
    

    【讨论】:

    • 我把这个放在哪里?并记住大多数子视图都有自己的触摸开始实现。
    • 直接你把这个保存在.m文件中并替换你的视图。
    • 对不起,我不明白你的想法是什么。
    【解决方案3】:

    创建一个 hittestintercept 视图。这可以使下面的视图像以前一样处理事件。

    @protocol HitTestInterceptViewDelegate <NSObject>
    
    - (BOOL)interceptHitTest:(CGPoint)point withEvent:(UIEvent *)event;
    
    @end
    
    @interface HitTestInterceptView : UIView
    
    @property(nonatomic, weak) id<HitTestInterceptViewDelegate> hitTestInterceptDelegate;
    
    @end
    

    HtiTestInterceptView.m

    #import "HitTestInterceptView.h"
    
    @implementation HitTestInterceptView
    
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        if ([_hitTestInterceptDelegate interceptHitTest:point withEvent:event] == NO) {
            return [super hitTest:point withEvent:event];
        }
        return nil;
    }
    
    @end
    

    然后在 toast 视图中使用它

    - (void)dismissIfTouchOutsideInView:(UIView *)view {
        if (_interceptView != nil) return;
        _interceptView = [[HitTestInterceptView alloc] initWithFrame:view.bounds];
        _interceptView.backgroundColor = [UIColor clearColor];
        _interceptView.hitTestInterceptDelegate = self;
        [view insertSubview:_interceptView belowSubview:self];
    }
    
    - (BOOL)interceptHitTest:(CGPoint)point withEvent:(UIEvent *)event {
        dispatch_async(dispatch_get_main_queue(), ^{
            // [self dismiss];
        });
        return YES;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-04-12
      • 1970-01-01
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多