溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

大前端代碼重構(gòu)之事件攔截iOS?Flutter?Vue怎么實(shí)現(xiàn)

發(fā)布時(shí)間:2023-04-04 11:23:49 來(lái)源:億速云 閱讀:243 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇“大前端代碼重構(gòu)之事件攔截iOS Flutter Vue怎么實(shí)現(xiàn)”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來(lái)看看這篇“大前端代碼重構(gòu)之事件攔截iOS Flutter Vue怎么實(shí)現(xiàn)”文章吧。

    一、需求來(lái)源

    app需要支持實(shí)現(xiàn)游客模式,啟動(dòng)后直接進(jìn)入首頁(yè)菜單,但是進(jìn)入二級(jí)頁(yè)則自動(dòng)調(diào)用登錄頁(yè)面??偨Y(jié)需求就是父視圖攔截子視圖的響應(yīng)事件,思考之后發(fā)現(xiàn)在事件響應(yīng)鏈上做攔截是最優(yōu)方法。

    二、iOS 事件攔截

    使用示例

    absorbing 屬性為 true 時(shí),會(huì)攔截子視圖的事件。點(diǎn)擊 button 時(shí)只會(huì)調(diào)用 absorbPointerView(綠色) 的響應(yīng)方法。

    absorbing 屬性為 false 時(shí),不會(huì)攔截子視圖的事件。點(diǎn)擊 button 時(shí)只會(huì)調(diào)用 button(藍(lán)色)的響應(yīng)方法。

    大前端代碼重構(gòu)之事件攔截iOS?Flutter?Vue怎么實(shí)現(xiàn)

    import UIKit
    import SnapKit
    import SwiftExpand
    /**
     通過(guò)遞歸遍歷將所有子視圖設(shè)置 isUserInteractionEnabled = false,則該視圖可以響應(yīng)事件;
     */
    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,用來(lái)攔截它子視圖事件。

    import UIKit
    class NNAbsorbPointerView: UIView {
        /// 是否攔截響應(yīng)
        var absorbing = false;
        // **MARK: - 重寫(xiě)加載方法**
        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.判斷點(diǎn)在不在當(dāng)前控件上
            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 時(shí),會(huì)攔截子視圖的事件。點(diǎn)擊藍(lán)色 Container 時(shí)只會(huì)調(diào)用綠色 Container 的響應(yīng)方法。

    absorbing 屬性為 false 時(shí),不會(huì)攔截子視圖的事件。點(diǎn)擊藍(lán)色 Container 時(shí)只會(huì)調(diào)用藍(lán)色 Container 的響應(yīng)方法。

    大前端代碼重構(gòu)之事件攔截iOS?Flutter?Vue怎么實(shí)現(xiàn)

    //
    //  AbsorbPointerDemo.dart
    //  flutter_templet_project
    //
    //  Created by shang on 10/25/21 11:05 AM.
    //  Copyright ? 10/25/21 shang. All rights reserved.
    //
    // AbsorbPointer本身可以接收點(diǎn)擊事件,消耗掉事件,而IgnorePointer無(wú)法接收點(diǎn)擊事件,其下的控件可以接收到點(diǎn)擊事件(不是子控件)。
    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('不可點(diǎn)擊:absorbing: ${_disable}'),
                  Switch(
                    value: _disable,
                    onChanged: (bool val) {
                      _disable = val;
                      setState(() {});
                    },
                  )
                ],
              ),
              Divider(),
              _buildAbsorbPointerNew(absorbing: _disable),
              MaterialButton(
                color: Colors.lightBlue,
                onPressed: () => onClick('我是外面的按鈕,不受影響'),
                child: Text('我是外面的按鈕,不受影響'),
              ),
            ],
          ),
        );
      }
      /// 默認(rèn)吸收事件,攔截事件
      _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 事件攔截

    實(shí)現(xiàn)很簡(jiǎn)單,@click 添加修飾符 capture.stop 即可攔截子標(biāo)簽事件。

    點(diǎn)擊 button 時(shí),父視圖(綠色)會(huì)攔截響應(yīng)事件。

    大前端代碼重構(gòu)之事件攔截iOS?Flutter?Vue怎么實(shí)現(xiàn)

    <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>

    以上就是關(guān)于“大前端代碼重構(gòu)之事件攔截iOS Flutter Vue怎么實(shí)現(xiàn)”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI