温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

大前端代码重构之事件拦截iOS Flutter Vue怎么实现

发布时间:2023-04-04 11:23:49 来源:亿速云 阅读:310 作者:iii 栏目:开发技术

这篇“大前端代码重构之事件拦截iOS Flutter Vue怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“大前端代码重构之事件拦截iOS Flutter Vue怎么实现”文章吧。

    一、需求来源

    app需要支持实现游客模式,启动后直接进入首页菜单,但是进入二级页则自动调用登录页面。总结需求就是父视图拦截子视图的响应事件,思考之后发现在事件响应链上做拦截是最优方法。

    二、iOS 事件拦截

    使用示例

    absorbing 属性为 true 时,会拦截子视图的事件。点击 button 时只会调用 absorbPointerView(绿色) 的响应方法。

    absorbing 属性为 false 时,不会拦截子视图的事件。点击 button 时只会调用 button(蓝色)的响应方法。

    大前端代码重构之事件拦截iOS Flutter Vue怎么实现

    import UIKit
    import SnapKit
    import SwiftExpand
    /**
     通过递归遍历将所有子视图设置 isUserInteractionEnabled = false,则该视图可以响应事件;
     */
    class NNAbsorbPointerViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            edgesForExtendedLayout = []
            view.backgroundColor = .white
            title = "NNAbsorbPointerView"
            absorbPointerView.addSubview(button)
            view.addSubview(absorbPointerView)
    //        view.recursion{ e in
    //            e.isUserInteractionEnabled = false;
    //        }
            view.addGestureTap { reco in
                debugPrint("\(Date()):reco.view")
            }
        }
        override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
            let edge = UIEdgeInsets(all: 50)
            button.snp.makeConstraints { make in
                make.edges.equalToSuperview().inset(edge)
            }
            absorbPointerView.snp.makeConstraints { make in
                make.edges.equalToSuperview().inset(edge)
            }
        }
        lazy var absorbPointerView: NNAbsorbPointerView = {
            let view = NNAbsorbPointerView(frame: .zero);
            view.absorbing = true;
            view.backgroundColor = .green;
            view.addGestureTap { reco in
                debugPrint("\(Date()):NNAbsorbPointerView")
            }
            return view
        }()
        lazy var button: UIButton = {
            let view = UIButton(type: .custom);
            view.setTitle("UIButton", for: .normal)
            view.setTitleColor(.white, for: .normal)
            view.backgroundColor = .blue;
            view.addGestureTap { reco in
                debugPrint("\(Date()):button")
            }
            return view
        }()
    }

    2、自定义视图 NNAbsorbPointerView,用来拦截它子视图事件。

    import UIKit
    class NNAbsorbPointerView: UIView {
        /// 是否拦截响应
        var absorbing = false;
        // **MARK: - 重写加载方法**
        override init(frame: CGRect) {
            super.init(frame: frame);
        }
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        override func layoutSubviews() {
            super.layoutSubviews()
        }
        override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
            if absorbing {
                return self
            }
            // 1.判断能不能处理事件
            if isUserInteractionEnabled == false, isHidden, alpha <= 0.01 {
                return nil
            }
            // 2.判断点在不在当前控件上
            if self.point(inside: point, with: event) == false {
                return nil;
            }
            for subView in subviews.reversed() {
                let subPoint = self.convert(point, to: subView);
                if let targetView = subView.hitTest(subPoint, with: event) {
                    return targetView;
                }
            }
            return self
        }
        // **MARK: - 私有方法**
    }

    三、Flutter 事件拦截

    使用示例

    absorbing 属性为 true 时,会拦截子视图的事件。点击蓝色 Container 时只会调用绿色 Container 的响应方法。

    absorbing 属性为 false 时,不会拦截子视图的事件。点击蓝色 Container 时只会调用蓝色 Container 的响应方法。

    大前端代码重构之事件拦截iOS Flutter Vue怎么实现

    //
    //  AbsorbPointerDemo.dart
    //  flutter_templet_project
    //
    //  Created by shang on 10/25/21 11:05 AM.
    //  Copyright © 10/25/21 shang. All rights reserved.
    //
    // AbsorbPointer本身可以接收点击事件,消耗掉事件,而IgnorePointer无法接收点击事件,其下的控件可以接收到点击事件(不是子控件)。
    import "package:flutter/material.dart";
    import 'package:flutter_templet_project/extension/ddlog.dart';
    class AbsorbPointerDemo extends StatefulWidget {
      const AbsorbPointerDemo({Key? key}) : super(key: key);
      @override
      _AbsorbPointerDemoState createState() => _AbsorbPointerDemoState();
    }
    class _AbsorbPointerDemoState extends State<AbsorbPointerDemo> {
      bool _disable = false;
      bool _switchValue = false;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Absorbpointer'),
            centerTitle: true,
            elevation: 0,
          ),
          body: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Row(
                children: <Widget>[
                  Text('不可点击:absorbing: ${_disable}'),
                  Switch(
                    value: _disable,
                    onChanged: (bool val) {
                      _disable = val;
                      setState(() {});
                    },
                  )
                ],
              ),
              Divider(),
              _buildAbsorbPointerNew(absorbing: _disable),
              MaterialButton(
                color: Colors.lightBlue,
                onPressed: () => onClick('我是外面的按钮,不受影响'),
                child: Text('我是外面的按钮,不受影响'),
              ),
            ],
          ),
        );
      }
      /// 默认吸收事件,拦截事件
      _buildAbsorbPointerNew({bool absorbing = true}) {
        return InkWell(
          onTap: () => onClick("outside"),
          child: Container(
            color: Colors.green,
            padding: EdgeInsets.all(20),
            child: AbsorbPointer(
              absorbing: absorbing,
              child: InkWell(
                onTap: () => onClick("inside"),
                child: Container(
                  color: Colors.blue,
                  width: 200.0,
                  height: 100.0,
                  alignment: Alignment.center,
                  child: Text("Container"),
                ),
              ),
            ),
          ),
        );
      }
      onClick(String msg) {
        debugPrint(msg);
      }
    }

    四、Web 事件拦截

    Vue 事件拦截

    实现很简单,@click 添加修饰符 capture.stop 即可拦截子标签事件。

    点击 button 时,父视图(绿色)会拦截响应事件。

    大前端代码重构之事件拦截iOS Flutter Vue怎么实现

    <template>
      <h3>{{ $route.meta.title }}</h3>
      <!-- <h3>{{ JSON.stringify(route) }}</h3> -->
      <div class="page" @click.capture.stop="doThis">
        <button @click="onClick">button</button>
      </div>
    </template>
    <script setup>
    import { getCurrentInstance, ref, reactive, watch, onMounted, } from 'vue';
    import { useRouter, useRoute } from 'vue-router';
    const router = useRouter();
    const route = useRoute();
    const doThis = () => {
      console.log(`${new Date()}: doThis`);
    };
    const onClick = () => {
      console.log(`${new Date()}: onClick`);
    };
    </script>
    <style scoped lang='scss'>
    .page{
      background-color: green; 
    }
    </style>

    以上就是关于“大前端代码重构之事件拦截iOS Flutter Vue怎么实现”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI