• weex开发的笔记


    启动npm服务 npm run serve:lazy相当于本地发布服务,连接本地服务可实时查看weex页面的更新

    向weex端注册方法和组件

    /// 功能组件
    [WXSDKEngine registerModule:@"MallModule" withClass:NSClassFromString(@"BHEMallWxEventModule")];
    /// UI组件
    [WXSDKEngine registerComponent:@"input" withClass:NSClassFromString(@"BHEWeexEditText")];

    设置下载等自定义代理和注入JS函数

    /// 实现自定义代理
    [WXSDKEngine registerHandler:loader withProtocol:@protocol(WXImgLoaderProtocol)];
    [WXSDKEngine registerHandler:loader withProtocol:@protocol(WXURLRewriteProtocol)];
    
    /// 注入JS服务函数
    /**
     * @abstract Registers a component for a given name, options and js code
     *
     * @param name The service name to register
     *
     * @param options The service options to register
     *
     * @param serviceScript service js code to invoke
     *
     */
    + (void)registerService:(NSString *)name withScript:(NSString *)serviceScript withOptions:(NSDictionary * _Nullable)options;

    Module提供方法给到weex端使用

    /// weex端调用时方法名为最前面部分addEventListener(xx,(ret)=>{code;}),其他按照参数个数依次补充即可,不需要补充方法名
    WX_EXPORT_METHOD(@selector(addEventListener:callback:))

    weex端写一个js功能模块

    /// date_utils.js
    const ONE_SECOND = 1000;
    const ONE_MINUTE = 60 * ONE_SECOND;
    const ONE_HOUR = 60 * ONE_MINUTE;
    const ONE_DAY = 24 * ONE_HOUR;
    
    export default {
      one_day: ONE_DAY,
      one_hour: ONE_HOUR,
      one_minute: ONE_MINUTE,
      one_second: ONE_SECOND,
      getSystemCurrTime() {//只到秒
        var timestamp = Date.parse(new Date());
        //var timestamp = (new Date()).valueOf();
        //var timestamp=new Date().getTime();
        return parseInt(timestamp / 1000);
      },
      getSystemCurrTime2() {//精度:毫秒
        var timestamp = Date.parse(new Date());
        //var timestamp = (new Date()).valueOf();
        //var timestamp=new Date().getTime();
        return parseInt(timestamp);
      },
      getCurrServerTime(serverTime) {
        if (!serverTime) {
          serverTime = 0;
        }
        return serverTime + this.getSystemCurrTime();
      },
      getTimeStrMDH(seconds) {
        var dateTime = new Date(seconds * 1000);
        var month = dateTime.getMonth() + 1;
        var day = dateTime.getDate();
        var hour = dateTime.getHours();
        return month + "月" + day + "日" + hour + "时";
      },
      calculateCutTime(timeInterval) {  //传进来的是毫秒的时间戳
        var day = parseInt(timeInterval / ONE_DAY);
        timeInterval %= ONE_DAY;
        var hour = parseInt(timeInterval / ONE_HOUR);
        timeInterval %= ONE_HOUR;
        var minute = parseInt(timeInterval / ONE_MINUTE);
        timeInterval %= ONE_MINUTE;
        var second = parseInt(timeInterval / ONE_SECOND);
        if (day <= 9) day = '0' + day;
        if (hour <= 9) hour = '0' + hour;
        if (minute <= 9) minute = '0' + minute;
        if (second <= 9) second = '0' + second;
    
        return [day, hour, minute, second];
      },
      getCountTime(time) {
        var countTime = '';
        var day = parseInt(time / ONE_DAY);
        time %= ONE_DAY;
        var hour = parseInt(time / ONE_HOUR);
        time %= ONE_HOUR;
        var minute = parseInt(time / ONE_MINUTE);
        time %= ONE_MINUTE;
        var second = parseInt(time / ONE_SECOND);
        if (day <= 9) day = '0' + day;
        if (hour <= 9) hour = '0' + hour;
        if (minute <= 9) minute = '0' + minute;
        if (second <= 9) second = '0' + second;
        countTime = day + '天' + hour + '时' + minute + '分' + second + '秒';
        return countTime;
      },
      getCountTime3(time) {
        var countTime = '';
        var day = parseInt(time / ONE_DAY);
        time %= ONE_DAY;
        var hour = parseInt(time / ONE_HOUR);
        time %= ONE_HOUR;
        var minute = parseInt(time / ONE_MINUTE);
        time %= ONE_MINUTE;
        var second = parseInt(time / ONE_SECOND);
        if (hour <= 9) hour = '0' + hour;
        if (minute <= 9) minute = '0' + minute;
        if (second <= 9) second = '0' + second;
        if (day > 0) {
          countTime = day + '天' + hour + '小时' + minute + '分';
        } else {
          countTime = hour + '小时' + minute + '分' + second + '秒';
        }
        return countTime;
      },
      getCountTime2(time) {
        var countTime = '';
        var day = parseInt(time / ONE_DAY);
        time %= ONE_DAY;
        var hour = parseInt(time / ONE_HOUR);
        time %= ONE_HOUR;
        var minute = parseInt(time / ONE_MINUTE);
        time %= ONE_MINUTE;
        var second = parseInt(time / ONE_SECOND);
        if (day > 0) {
          countTime += day + '天';
          countTime += hour + '小时';
          countTime += minute + '分';
          countTime += second + '秒';
        } else {
          if (hour > 0) {
            countTime += hour + '小时';
            countTime += minute + '分';
            countTime += second + '秒';
          } else {
            if (minute > 0) {
              countTime += minute + '分';
              countTime += second + '秒';
            } else {
              if (second > 0) {
                countTime += second + '秒';
              }
            }
          }
        }
        return countTime;
      },
      dateFormat(dateTime, fmt) {
        if (!dateTime) {
          return dateTime
        }
        if (typeof dateTime == 'string' && !isNaN(dateTime)) {
          dateTime = +dateTime
        }
        dateTime = new Date(dateTime);
        var o = {
          "M+": dateTime.getMonth() + 1, //月份
          "d+": dateTime.getDate(), //
          "h+": dateTime.getHours(), //小时
          "m+": dateTime.getMinutes(), //
          "s+": dateTime.getSeconds(), //
          "q+": Math.floor((dateTime.getMonth() + 3) / 3), //季度
          "S": dateTime.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (dateTime.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
          if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
      }
    }

    使用定义的js功能模块时(相当于创建对象实例)

    import dateUtil from './utils/date_utils.js';

    引用其他vue文件的UI组件

      import navigationBar from "./navigator.vue";
      import noNetworking from './no_networking.vue';
      import pro_tag from '../items/pro_tag.vue';
    
    /// 通过模块名字实例化原生模块对象用作调用原生模块方法
      const dom = weex.requireModule('dom');
      const myModule = weex.requireModule('MallModule');
      const navigator = weex.requireModule('navigator');
    
      export default {
        components: { navigationBar, noNetworking, pro_tag },
     }
    

     weex调用原生方法

    getUserInfo(callback) {
        var msg = {
          "operation": "getUserInfo"
        };
        // myModule.log('请求获取用户信息');
        bridgeModule.commandInterface(JSON.stringify(msg), function (e) {
          var json = JSON.parse(e);
          // myModule.log('用户信息:' + e);
          if (callback) {
            callback(json);
          }
        }, function (failed) {
          // myModule.log('获取登用户息失败:' + failed);
          if (callback) {
            callback({});
          }
        })
      },
    
    
    WX_EXPORT_METHOD(@selector(commandInterface:finalCallBack:finalCallbackFail:))
    -(void)commandInterface:(NSString *)param finalCallBack:(WXModuleKeepAliveCallback)callback finalCallbackFail:(WXModuleKeepAliveCallback)failCallback

     weex给控件赋值样式的几个方式

    /// 样式应该为class加上style
    /// 直接在标签内作为属性编写
    <text v-else-if="item.nOriginalPrice>item.nSalePrice" style="font-family: PingFang-SC-Medium;font-size: 24px;color: #C7C7CC;text-align: left;text-decoration: line-through;">¥{{item.nOriginalPrice/100.0}}</text>
    
    /// 通过函数获取
    <div :style="appUtil.grayFloatStyle" v-if="appUtil.showGrayFloat()"></div>
    
    /// 通过函数给属性赋值
    <div class="singleTag" :style="{backgroundColor:getTagColor(item.oTagInfo.SingleTag.TagColor),borderBottomRightRadius:item.lProMemPrice && item.lProMemPrice>0?'0':'18px'}" v-if="item.oTagInfo&&item.oTagInfo.SingleTag&&item.oTagInfo.SingleTag.TagName">
    
    /// 通过css定义
    <div class="wrapper" @click="cancelAddressSelect">
    
    <style scoped>
      .wrapper {
        position: absolute;
        top: -100px;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(0, 0, 0, 0.5);
      }
    
      .address_selector {
        background-color: #fff;
        position: absolute;
        bottom: 0;
        left: 0;
        width: 750px;
        height: 640px;
        border-top-right-radius: 20px;
        border-top-left-radius: 20px;
        overflow: hidden;
      }
    </style>
    
    /// 通过函数表达式获取值

    给视图元素增加事件

    /// @事件="函数(arvgs...)"
    <image :src="local_image.icon_sending_cancel" class="cancelBtn" @click="closeDialog()"></image>
    <input class="inputText" maxlength="30" @input="aliAccountInput" :value="aliaccount" @change="aliAccountInput"/>
    <list v-if="hasLoadData" style="flex: 1;  750px; margin-top: -1px;" @loadmore="onloadMoreHandle" @scroll="onScroll">
    <div class="slider-pages" v-for="(item, i) in bannerList" :key="I" @click="jumpToActivePage(item,'banner',i)" @appear="appear(item,i)">
    <app_dialog v-if="isShowNewGiftReceiveFailDialog" tipMsgText="请重试" messageText="领取失败" confirmText="确定" v-on:confirmClick="confirmReceiveGiftPackageDialog"></app_dialog>
        <div v-if="isShowNewGiftReceiveSuccessDialog" style=" 750px; position: absolute; top: -88px; left: 0; bottom: 0; background-color: rgba(0,0,0,0); justify-content: center; align-items: center;">
          <div style=" 180px; height: 180px; justify-content: center; align-items: center;background-color: rgba(0,0,0,0.8); border-radius: 12px;">
            <image style=" 80px;height: 80px; margin-bottom: 20px;" :src="remote_image.receive_success"></image>
            <text style="font-size: 24px; color: #fff; text-align: center;">领取成功</text>
          </div>
        </div>

    处理圆角等超出显示范围的时候显示效果配置的属性overflow   https://www.w3school.com.cn/css/pr_pos_overflow.asp

    给元素绑定别名,用于后续获取

    /// ref
    <div v-if="showPromoteDialog" ref="refPromoteDialog" class="fullScreenDiv prompt_bg">
          <div style="align-items: flex-end">
            <image style=" 100px; height: 100px; opacity: 0"
                   :src="remote_image.close_envelope_btn"
                   @click="closePrompt"
                   ref="closeImg"></image>
            <image style="margin-top: 10px;  520px; height: 780px"
                   :src="promoteDialogData.img"
                   @click="toPromotePage"
                   @load="onPromoteImageLoad"></image>
          </div>
        </div>
    
    const refPromoteDialog = this.$refs.refPromoteDialog;
    const closeImg = this.$refs.closeImg;

    自定义组件通过props来提供给外部调用设置属性值

    <template>
        <div v-if="showDialog" @click="" style="750px;position:absolute;top:0;bottom:0;flex:1;">
            <div style="750px;position:absolute;top:-88px;bottom:0;background-color:#000000;opacity:0.75;flex:1;">
            </div>
            <div class="tip-bg" style="background-color: #051C4F;">
                <image style="534px; height: 586px;position:absolute;" :src="remote_image.dialog_fail_bg"></image>
                <image style="318px; height: 262px;margin-top:61px;" :src="remote_image.dialog_fail_headIcon"></image>
                <text class="tip-content">活动已下线,逛逛别的吧~</text>  
                <image style="221px; height: 72px;margin-top:46px;" :src="remote_image.dialog_fail_button" @click="onClickOver"></image>
            </div>
        </div>
    </template>
    
    <script>
    import image from '../../../data/image_index.js';
    import myImage from '../../../data/image_b_activity.js';
    
    export default {
        data() {
            return {
                remote_image: myImage.remote
            };
        },
        props: {
            showDialog: {
                type: Boolean,
                default: false,
            }
        },
        methods: {
            onClickOver() {
                this.$emit('onClickOver');
            },
        }
    }
    </script>
    
    <style scope>
    .tip-bg{
        position:absolute;
        top:359px;
        width:534px;
        height:586px;
        margin-top:0px;
        margin-left:108px;
        align-items: center;
    }
    
    .tip-title{
        margin-top:2px;
        margin-left: 151px;
        font-family: PingFangSC-Regular;
        color:#000000;
        font-size:34px;
        font-weight: bold;
        line-height: 34px;
        letter-spacing: 0;
    }
    
     .tip-content{
        font-family: FZLTHJW--GB1-0;
        font-size: 24px;
        color: #FFFFFF;
        letter-spacing: 1px;
        text-align: center;
        line-height: 32px;
        text-shadow: 0 2px 3px rgba(0,0,0,0.50);
        margin-top: 19px;
     }
    </style>

    自定义组件通过$emit给外界提供事件触发方法代理

    export default {
        data() {
            return {
                remote_image: myImage.remote
            };
        },
        props: {
            strUid:{
                type: String,
                default: null,
            },
            showDialog: {
                type: Boolean,
                default: false,
            }
        },
        methods: {
            onClickModify() {
                this.$emit('onClickModify');
            },
    
            onClickSure() {
                this.$emit('onClickSure');
            }
        }
    }

     看一下给组件增加事件的文件WXComponent+Events.m

    #import "WXComponent+Events.h"
    #import "WXComponent.h"
    #import "WXComponent_internal.h"
    #import "WXSDKInstance.h"
    #import "WXComponentManager.h"
    #import "WXAssert.h"
    #import "WXUtility.h"
    #import "WXSDKManager.h"
    #import "WXSDKInstance_private.h"
    #import "WXDefine.h"
    #import "WXRecycleListComponent.h"
    #import "WXRecycleListDataManager.h"
    #import <objc/runtime.h>
    #import <UIKit/UIGestureRecognizerSubclass.h>
    #import "WXComponent+PseudoClassManagement.h"
    #import "WXCoreBridge.h"
    
    #pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
    
    @interface UITouch (WXTouchGestureRecognizer)
    @property (nonatomic, strong) NSNumber *wx_identifier;
    @property (nonatomic, strong) NSNumber *wx_stopPropagation;
    @end
    
    @implementation UITouch (WXTouchGestureRecognizer)
    - (NSNumber *)wx_identifier
    {
        return objc_getAssociatedObject(self, _cmd);
    }
    
    - (void)setWx_identifier:(NSNumber *)wx_identifier
    {
        objc_setAssociatedObject(self, @selector(wx_identifier), wx_identifier, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSNumber *)wx_stopPropagation
    {
        return objc_getAssociatedObject(self, _cmd);
    }
    
    - (void)setWx_stopPropagation:(NSNumber *)wx_stopPropagation
    {
        objc_setAssociatedObject(self, @selector(wx_stopPropagation), wx_stopPropagation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    @end
    
    @interface UIGestureRecognizer (WXGesture)
    @property (nonatomic, strong) NSNumber *wx_identifier;
    @end
    
    @implementation UIGestureRecognizer (WXGesture)
    - (NSNumber *)wx_identifier
    {
        NSNumber *identifier = objc_getAssociatedObject(self, _cmd);
        if (!identifier) {
            static NSUInteger _gestureIdentifier;
            identifier = @(_gestureIdentifier++);
            self.wx_identifier = identifier;
        }
        
        return identifier;
    }
    
    - (void)setWx_identifier:(NSNumber *)wx_identifier
    {
        objc_setAssociatedObject(self, @selector(wx_identifier), wx_identifier, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    @end
    
    @interface WXTouchGestureRecognizer : UIGestureRecognizer
    
    @property (nonatomic, assign) BOOL listenTouchStart;
    @property (nonatomic, assign) BOOL listenTouchMove;
    @property (nonatomic, assign) BOOL listenTouchEnd;
    @property (nonatomic, assign) BOOL listenTouchCancel;
    @property (nonatomic, assign) BOOL listenPseudoTouch;
    
    - (instancetype)initWithComponent:(WXComponent *)component NS_DESIGNATED_INITIALIZER;
    
    @end
    
    @interface WXEventManager :NSObject
    + (instancetype) sharedManager;
    - (BOOL)stopPropagation:(NSString *)instanceId ref:(NSString *)ref type:(NSString *)type params:(NSDictionary *)params;
    @end
    
    @implementation WXEventManager
    
    - (instancetype) init
    {
        self = [super init];
        return self;
    }
    
    + (instancetype)sharedManager
    {
        static id _sharedInstance = nil;
        static dispatch_once_t oncePredicate;
        dispatch_once(&oncePredicate, ^{
            _sharedInstance = [[self alloc] init];
        });
        return _sharedInstance;
    }
    
    - (BOOL)stopPropagation:(NSString *)instanceId ref:(NSString *)ref type:(NSString *)type params:(NSDictionary *)params
    {
        JSValue *value = [[WXSDKManager bridgeMgr] fireEventWithResult:instanceId ref:ref type:type params:params domChanges:nil];
        
        if ([value.toString isEqualToString:@"true"]) {
            return YES;
        }
        return NO;
    }
    
    @end
    
    @implementation WXComponent (Events)
    
    #pragma mark Public
    
    - (void)fireEvent:(NSString *)eventName params:(NSDictionary *)params
    {
        [self fireEvent:eventName params:params domChanges:nil];
    }
    
    - (void)fireEvent:(NSString *)eventName params:(NSDictionary *)params domChanges:(NSDictionary *)domChanges
    {
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        NSTimeInterval timeSp = [[NSDate date] timeIntervalSince1970] * 1000;
        [dict setObject:@(timeSp) forKey:@"timestamp"];
        if (params) {
            [dict addEntriesFromDictionary:params];
        }
        WXRecycleListComponent *recyleListComponent  = (WXRecycleListComponent*)[self getRecycleListComponent];
        if (recyleListComponent) {
            NSIndexPath *indexPath = [((UICollectionView*)recyleListComponent.view) indexPathForItemAtPoint:[self.view.superview
                                                                                                              convertPoint:self.view.center toView:recyleListComponent.view]];
            NSString *templateId = [self recursiveFindTemplateIdWithComponent:self];
            NSString *virtualComponentId = [recyleListComponent.dataManager virtualComponentIdWithIndexPath:indexPath templateId:templateId];
            if (virtualComponentId) {
                dict[@"componentId"] = virtualComponentId;
            }
        }
        
        NSArray *handlerArguments = [self _paramsForEvent:eventName];
        NSString *ref = _templateComponent ? _templateComponent.ref  : self.ref;
        [[WXSDKManager bridgeMgr] fireEvent:self.weexInstance.instanceId ref:ref type:eventName params:dict domChanges:domChanges handlerArguments:handlerArguments];
    }
    
    - (NSString *)recursiveFindTemplateIdWithComponent:(WXComponent *)component
    {
        if (!component) {
            return nil;
        }
        if ([component isKindOfClass:NSClassFromString(@"WXCellSlotComponent")]) {
            return nil;
        }
        if (component.attributes[@"@templateId"]) {
            return component.attributes[@"@templateId"];
        }
        return [self recursiveFindTemplateIdWithComponent:component.supercomponent];
    }
    
    - (void)addEvent:(NSString *)addEventName
    {
        WXAssertMainThread();
    }
    
    - (void)removeEvent:(NSString *)removeEventName
    {
        WXAssertMainThread();
    }
    
    #pragma mark Add & Remove Event
    
    #define WX_ADD_EVENT(eventName, addSelector) 
    if ([addEventName isEqualToString:@#eventName]) {
        [self addSelector];
    }
    
    #define WX_ADD_EVENTS(eventName1,eventName2, addSelector) 
    if ([addEventName isEqualToString:@#eventName1]||[addEventName isEqualToString:@#eventName2]) {
        [self addSelector:addEventName];
    }
    
    #define WX_REMOVE_EVENT(eventName, removeSelector) 
    if ([removeEventName isEqualToString:@#eventName]) {
        [self removeSelector];
    }
    
    #define WX_REMOVE_EVENTS(eventName1,eventName2, removeSelector) 
    if ([removeEventName isEqualToString:@#eventName1]||[removeEventName isEqualToString:@#eventName2]) {
        [self removeSelector];
    }
    
    - (void)_initEvents:(NSArray *)events
    {
        for (NSString *addEventName in events) {
            [self _addEventOnMainThread:addEventName];
        }
    }
    
    - (void)_initPseudoEvents:(BOOL)isListenPseudoTouch
    {
        if(isListenPseudoTouch) {
            self.touchGesture.listenPseudoTouch = YES;
        }
    }
    
    - (void)_addEventOnMainThread:(NSString *)addEventName
    {
        if (![self isViewLoaded]) {
            //This action will be ignored While the view is loaded,
            //then it will initEvent according to the records in _events
            return;
        }
        WX_ADD_EVENT(appear, addAppearEvent)
        WX_ADD_EVENT(disappear, addDisappearEvent)
        
        WX_ADD_EVENT(click, addClickEvent)
        WX_ADD_EVENT(swipe, addSwipeEvent)
        WX_ADD_EVENT(longpress, addLongPressEvent)
        
        WX_ADD_EVENT(panstart, addPanStartEvent)
        WX_ADD_EVENT(panmove, addPanMoveEvent)
        WX_ADD_EVENT(panend, addPanEndEvent)
        
        WX_ADD_EVENT(horizontalpan, addHorizontalPanEvent)
        WX_ADD_EVENT(verticalpan, addVerticalPanEvent)
        
        WX_ADD_EVENT(touchstart, addTouchStartEvent)
        WX_ADD_EVENT(touchmove, addTouchMoveEvent)
        WX_ADD_EVENT(touchend, addTouchEndEvent)
        WX_ADD_EVENT(touchcancel, addTouchCancelEvent)
        WX_ADD_EVENT(accessibilityMagicTap, addAccessibilityMagicTapEvent)
        
        WX_ADD_EVENTS(stopPropagation, stoppropagation, addStopPropagationEvent)
        
        if(_isListenPseudoTouch) {
            self.touchGesture.listenPseudoTouch = YES;
        }
        
        [self addEvent:addEventName];
    }
    
    - (void)_removeEventOnMainThread:(NSString *)removeEventName
    {
        WX_REMOVE_EVENT(appear, removeAppearEvent)
        WX_REMOVE_EVENT(disappear, removeDisappearEvent)
        
        WX_REMOVE_EVENT(click, removeClickEvent)
        WX_REMOVE_EVENT(swipe, removeSwipeEvent)
        WX_REMOVE_EVENT(longpress, removeLongPressEvent)
        
        WX_REMOVE_EVENT(panstart, removePanStartEvent)
        WX_REMOVE_EVENT(panmove, removePanMoveEvent)
        WX_REMOVE_EVENT(panend, removePanEndEvent)
        
        WX_REMOVE_EVENT(horizontalpan, removeHorizontalPanEvent)
        WX_REMOVE_EVENT(verticalpan, removeVerticalPanEvent)
        
        WX_REMOVE_EVENT(touchstart, removeTouchStartEvent)
        WX_REMOVE_EVENT(touchmove, removeTouchMoveEvent)
        WX_REMOVE_EVENT(touchend, removeTouchEndEvent)
        WX_REMOVE_EVENT(touchcancel, removeTouchCancelEvent)
        WX_REMOVE_EVENT(accessibilityMagicTap, removeAccessibilityMagicTapEvent)
        
        WX_REMOVE_EVENTS(stoppropagation,stopPropagation, removeStopPropagationEvent)
    
        if(_isListenPseudoTouch) {
            self.touchGesture.listenPseudoTouch = NO;
        }
    
        [self removeEvent:removeEventName];
    }
    
    - (void)_removeAllEvents
    {
        [self removeClickEvent];
        [self removeLongPressEvent];
        [self removePanStartEvent];
        [self removePanMoveEvent];
        [self removePanEndEvent];
        [self removeHorizontalPanEvent];
        [self removeVerticalPanEvent];
        
        [self removeTouchStartEvent];
        [self removeTouchMoveEvent];
        [self removeTouchEndEvent];
        [self removeTouchCancelEvent];
        [self removeSwipeEvent];
        [self removePseudoTouchEvent];
    }
    
    - (void)_collectSubcomponents:(NSMutableArray *)components
    {
        for (WXComponent* c in _subcomponents) {
            [components addObject:c];
            [c _collectSubcomponents:components];
        }
    }
    
    #pragma mark - Appear & Disappear
    
    - (void)addAppearEvent
    {
        _appearEvent = YES;
        [self.ancestorScroller addScrollToListener:self];
    }
    
    - (void)addDisappearEvent
    {
        _disappearEvent = YES;
        [self.ancestorScroller addScrollToListener:self];
    }
    
    - (void)removeAppearEvent
    {
        _appearEvent = NO;
        [self.ancestorScroller removeScrollToListener:self];
    }
    
    - (void)removeDisappearEvent
    {
        _disappearEvent = NO;
        [self.ancestorScroller removeScrollToListener:self];
    }
    
    - (void)removePseudoTouchEvent
    {
        _touchGesture.listenPseudoTouch = NO;
        [self checkRemoveTouchGesture];
    }
    
    #pragma mark - Accessibility Event
    
    - (void)addAccessibilityMagicTapEvent
    {
        _accessibilityMagicTapEvent = YES;
    }
    
    - (void)removeAccessibilityMagicTapEvent
    {
        _accessibilityMagicTapEvent = NO;
    }
    
    #pragma mark - StopPropagation
    
    - (void)addStopPropagationEvent:(NSString *)stopPropagationName
    {
        _listenStopPropagation = YES;
        _stopPropagationName = stopPropagationName;
        self.touchGesture.listenTouchMove = YES;
    }
    
    - (void)removeStopPropagationEvent
    {
        _listenStopPropagation = NO;
        self.touchGesture.listenTouchMove = NO;
    }
    
    #pragma mark - Click Event
    
    - (void)addClickEvent
    {
        if (!_tapGesture) {
            _tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onClick:)];
            _tapGesture.delegate = self;
            _tapGesture.cancelsTouchesInView = _cancelsTouchesInView;
            [self.view addGestureRecognizer:_tapGesture];
        }
    }
    
    - (void)removeClickEvent
    {
        if (_tapGesture) {
            _tapGesture.delegate = nil;
            if ([self isViewLoaded]) {
                if ([self.view.gestureRecognizers containsObject:_tapGesture]) {
                    [self.view removeGestureRecognizer:_tapGesture];
                }
            }
            @try {
                [_tapGesture removeTarget:self action:@selector(onClick:)];
            }@catch(NSException *exception) {
                WXLog(@"%@", exception);
            }
            _tapGesture = nil;
        }
    }
    
    - (void)onClick:(__unused UITapGestureRecognizer *)recognizer
    {
        NSMutableDictionary *position = [[NSMutableDictionary alloc] initWithCapacity:4];
        CGFloat scaleFactor = self.weexInstance.pixelScaleFactor;
        if (![self isViewLoaded]) {
            return;
        }
        if (!CGRectEqualToRect(self.view.frame, CGRectZero)) {
            CGRect frame = [self.view.superview convertRect:self.view.frame toView:self.view.window];
            position[@"x"] = @(frame.origin.x/scaleFactor);
            position[@"y"] = @(frame.origin.y/scaleFactor);
            position[@"width"] = @(frame.size.width/scaleFactor);
            position[@"height"] = @(frame.size.height/scaleFactor);
        }
        [self fireEvent:@"click" params:@{@"position":position}];
    }
    
    #pragma mark - Swipe event
    
    - (void)addSwipeEvent
    {
        if (_swipeGestures) {
            return;
        }
        
        _swipeGestures = [NSMutableArray arrayWithCapacity:4];
        
        // It's a little weird because the UISwipeGestureRecognizer.direction property is an options-style bit mask, but each recognizer can only handle one direction
        SEL selector = @selector(onSwipe:);
        UISwipeGestureRecognizer *upSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
                                                                                                action:selector];
        upSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
        upSwipeRecognizer.delegate = self;
        [_swipeGestures addObject:upSwipeRecognizer];
        [self.view addGestureRecognizer:upSwipeRecognizer];
        
        UISwipeGestureRecognizer *downSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
                                                                                                  action:selector];
        downSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionDown;
        downSwipeRecognizer.delegate = self;
        [_swipeGestures addObject:downSwipeRecognizer];
        [self.view addGestureRecognizer:downSwipeRecognizer];
        
        UISwipeGestureRecognizer *rightSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
                                                                                                   action:selector];
        rightSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
        rightSwipeRecognizer.delegate = self;
        [_swipeGestures addObject:rightSwipeRecognizer];
        [self.view addGestureRecognizer:rightSwipeRecognizer];
        
        UISwipeGestureRecognizer *leftSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
                                                                                                  action:selector];
        leftSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
        leftSwipeRecognizer.delegate = self;
        [_swipeGestures addObject:leftSwipeRecognizer];
        [self.view addGestureRecognizer:leftSwipeRecognizer];
    }
    
    - (void)removeSwipeEvent
    {
        if (_swipeGestures == nil) {
            return;
        }
      
        @try {
            for (UISwipeGestureRecognizer *recognizer in _swipeGestures) {
                recognizer.delegate = nil;
                if([self isViewLoaded]) {
                    if ([[self.view gestureRecognizers] containsObject:recognizer]) {
                        [self.view removeGestureRecognizer:recognizer];
                    }
                }
                [recognizer removeTarget:self action:@selector(onSwipe:)];
            }
        }@catch(NSException *exception) {
            WXLog(@"%@", exception);
        }
        _swipeGestures = nil;
    }
    
    - (void)onSwipe:(UISwipeGestureRecognizer *)gesture
    {
        if (![self isViewLoaded]) {
            return;
        }
        
        UISwipeGestureRecognizerDirection direction = gesture.direction;
        
        NSString *directionString;
        switch(direction) {
            case UISwipeGestureRecognizerDirectionLeft:
                directionString = @"left";
                break;
            case UISwipeGestureRecognizerDirectionRight:
                directionString = @"right";
                break;
            case UISwipeGestureRecognizerDirectionUp:
                directionString = @"up";
                break;
            case UISwipeGestureRecognizerDirectionDown:
                directionString = @"down";
                break;
            default:
                directionString = @"unknown";
                break;
        }
        
        CGPoint screenLocation = [gesture locationInView:self.view.window];
        CGPoint pageLoacation = [gesture locationInView:self.weexInstance.rootView];
        NSDictionary *resultTouch = [self touchResultWithScreenLocation:screenLocation pageLocation:pageLoacation identifier:gesture.wx_identifier];
        [self fireEvent:@"swipe" params:@{@"direction":directionString, @"changedTouches":resultTouch ? @[resultTouch] : @[]}];
    }
    
    #pragma mark - Long Press
    
    - (void)addLongPressEvent
    {
        if (!_longPressGesture) {
            _longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPress:)];
            _longPressGesture.delegate = self;
            [self.view addGestureRecognizer:_longPressGesture];
        }
    }
    
    - (void)removeLongPressEvent
    {
        if (_longPressGesture) {
            _longPressGesture.delegate = nil;
            if ([self isViewLoaded]) {
                if([[self.view gestureRecognizers] containsObject:_longPressGesture]) {
                    [self.view removeGestureRecognizer:_longPressGesture];
                }
            }
            @try {
                [_longPressGesture removeTarget:self action:@selector(onLongPress:)];
            }@catch(NSException * exception) {
                WXLog(@"%@", exception);
            }
            _longPressGesture = nil;
        }
    }
    
    - (void)onLongPress:(UILongPressGestureRecognizer *)gesture
    {
        if (![self isViewLoaded]) {
            return;
        }
        
        if (gesture.state == UIGestureRecognizerStateBegan) {
            CGPoint screenLocation = [gesture locationInView:self.view.window];
            CGPoint pageLoacation = [gesture locationInView:self.weexInstance.rootView];
            NSDictionary *resultTouch = [self touchResultWithScreenLocation:screenLocation pageLocation:pageLoacation identifier:gesture.wx_identifier];
            [self fireEvent:@"longpress" params:@{@"changedTouches":resultTouch ? @[resultTouch] : @[]}];
        } else if (gesture.state == UIGestureRecognizerStateEnded) {
            gesture.wx_identifier = nil;
        }
    }
    
    #pragma mark - Pan
    
    - (void)addPanGesture
    {
        if (!_panGesture) {
            _panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onPan:)];
            _panGesture.delegate = self;
            [self.view addGestureRecognizer:_panGesture];
        }
    }
    
    - (void)addPanStartEvent
    {
        _listenPanStart = YES;
        [self addPanGesture];
    }
    
    - (void)addPanMoveEvent
    {
        _listenPanMove = YES;
        [self addPanGesture];
    }
    
    - (void)addPanEndEvent
    {
        _listenPanEnd = YES;
        [self addPanGesture];
    }
    
    - (void)addHorizontalPanEvent
    {
        _listenHorizontalPan = YES;
        [self addPanGesture];
    }
    
    - (void)addVerticalPanEvent
    {
        _listenVerticalPan = YES;
        [self addPanGesture];
    }
    
    
    - (void)onPan:(UIPanGestureRecognizer *)gesture
    {
        if (![self isViewLoaded]) {
            return;
        }
        
        CGPoint screenLocation = [gesture locationInView:self.view.window];
        CGPoint pageLoacation = [gesture locationInView:self.weexInstance.rootView];
        NSString *eventName;
        NSString *state = @"";
        NSDictionary *resultTouch = [self touchResultWithScreenLocation:screenLocation pageLocation:pageLoacation identifier:gesture.wx_identifier];
        
        if (gesture.state == UIGestureRecognizerStateBegan) {
            if (_listenPanStart) {
                eventName = @"panstart";
            }
            state = @"start";
        } else if (gesture.state == UIGestureRecognizerStateEnded) {
            if (_listenPanEnd) {
                eventName = @"panend";
            }
            state = @"end";
            gesture.wx_identifier = nil;
        } else if (gesture.state == UIGestureRecognizerStateChanged) {
            if (_listenPanMove) {
                 eventName = @"panmove";
            }
            state = @"move";
        } else if (gesture.state == UIGestureRecognizerStateCancelled) {
            state = @"cancel";
        }
        
        CGPoint translation = [_panGesture translationInView:self.view];
        
        if (_listenHorizontalPan && (gesture.state != UIGestureRecognizerStateBegan || fabs(translation.y) <= fabs(translation.x))) {
            [self fireEvent:@"horizontalpan" params:@{@"state":state, @"changedTouches":resultTouch ? @[resultTouch] : @[]}];
        }
            
        if (_listenVerticalPan && (gesture.state != UIGestureRecognizerStateBegan || fabs(translation.y) >= fabs(translation.x))) {
            [self fireEvent:@"verticalpan" params:@{@"state":state, @"changedTouches":resultTouch ? @[resultTouch] : @[]}];
        }
            
        if (eventName) {
            [self fireEvent:eventName params:@{@"changedTouches":resultTouch ? @[resultTouch] : @[]}];
        }
    }
    
    - (void)removePanStartEvent
    {
        _listenPanStart = NO;
        [self checkRemovePanGesture];
    }
    
    - (void)removePanMoveEvent
    {
        _listenPanMove = NO;
        [self checkRemovePanGesture];
    }
    
    - (void)removePanEndEvent
    {
        _listenPanEnd = NO;
        [self checkRemovePanGesture];
    }
    
    - (void)removeHorizontalPanEvent
    {
        _listenHorizontalPan = NO;
        [self checkRemovePanGesture];
    }
    
    - (void)removeVerticalPanEvent
    {
        _listenVerticalPan = NO;
        [self checkRemovePanGesture];
    }
    
    - (void)checkRemovePanGesture
    {
        if (_panGesture
            && !_listenPanStart && !_listenPanMove && !_listenPanEnd
            && !_listenHorizontalPan && !_listenVerticalPan
            ) {
            
            if ([self isViewLoaded]) {
                if ([[self.view gestureRecognizers] containsObject:_panGesture]) {
                    [self.view removeGestureRecognizer:_panGesture];
                }
            }
            
            _panGesture.delegate = nil;
            @try {
                [_panGesture removeTarget:self action:@selector(onPan:)];
            }@catch(NSException * exception) {
                WXLog(@"%@", exception);
            }
            _panGesture = nil;
        }
    }
    
    #pragma mark - Touch Event
    
    - (WXTouchGestureRecognizer *)touchGesture
    {
        if (!_touchGesture) {
            _touchGesture = [[WXTouchGestureRecognizer alloc] initWithComponent:self];
            _touchGesture.delegate = self;
            [self.view addGestureRecognizer:_touchGesture];
        }
        return _touchGesture;
    }
    
    - (void)addTouchStartEvent
    {
        self.touchGesture.listenTouchStart = YES;
    }
    
    - (void)addTouchMoveEvent
    {
        self.touchGesture.listenTouchMove = YES;
    }
    
    - (void)addTouchEndEvent
    {
        self.touchGesture.listenTouchEnd = YES;
    }
    
    - (void)addTouchCancelEvent
    {
        self.touchGesture.listenTouchCancel = YES;
    }
    
    - (void)removeTouchStartEvent
    {
        _touchGesture.listenTouchStart = NO;
        [self checkRemoveTouchGesture];
    }
    
    - (void)removeTouchMoveEvent
    {
        _touchGesture.listenTouchMove = NO;
        [self checkRemoveTouchGesture];
    }
    
    - (void)removeTouchEndEvent
    {
        _touchGesture.listenTouchEnd = NO;
        [self checkRemoveTouchGesture];
    }
    
    - (void)removeTouchCancelEvent
    {
        _touchGesture.listenTouchCancel = NO;
        [self checkRemoveTouchGesture];
    }
    
    - (void)checkRemoveTouchGesture
    {
        if (_touchGesture && !_touchGesture.listenTouchStart && !_touchGesture.listenTouchMove && !_touchGesture.listenTouchEnd && !_touchGesture.listenTouchCancel && !_touchGesture.listenPseudoTouch) {
            _touchGesture.delegate = nil;
            if ([self isViewLoaded]) {
                if ([[self.view gestureRecognizers] containsObject:_touchGesture]) {
                    [self.view removeGestureRecognizer:_touchGesture];
                }
            }
            _touchGesture = nil;
        }
    }
    
    - (BOOL)gestureShouldStopPropagation:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
    {
        if(touch.wx_stopPropagation && [touch.wx_stopPropagation isEqualToNumber:@1]){
            return NO;
        }
        else
        {
            if (_listenStopPropagation)
            {
                NSString *ref = _templateComponent ? _templateComponent.ref : self.ref;
                CGPoint screenLocation = [touch locationInView:touch.window];
                CGPoint pageLocation = [touch locationInView:self.weexInstance.rootView];
                NSDictionary *resultTouch = [self touchResultWithScreenLocation:screenLocation pageLocation:pageLocation identifier:touch.wx_identifier];
                NSString *touchState;
                if (touch.phase == UITouchPhaseBegan) {
                    touchState = @"start";
                }
                else if (touch.phase == UITouchPhaseMoved){
                    touchState = @"move";
                }
                else{
                    touchState = @"end";
                }
                BOOL stopPropagation = [[WXEventManager sharedManager]stopPropagation:self.weexInstance.instanceId ref:ref type:_stopPropagationName params:@{@"changedTouches":resultTouch ? @[resultTouch] : @[],@"action":touchState}];
                touch.wx_stopPropagation = stopPropagation ? @1 : @0;
                
                //only custom event on custom component will make not receive touch
                //you can use custom-event="yes" to enable this feature
                return _customEvent ? !stopPropagation : YES;
            }
        }
        return YES;
    }
    
    #pragma mark - UIGestureRecognizerDelegate
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
    {
        return [self gestureShouldStopPropagation:gestureRecognizer shouldReceiveTouch:touch];
    }
    
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
    {
        if (gestureRecognizer == _panGesture) {
            CGPoint translation = [_panGesture translationInView:self.view];
            if (_listenHorizontalPan && !_listenVerticalPan && fabs(translation.y) > fabs(translation.x)) {
                return NO;
            }
        }
        return YES;
    }
    
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
        NSString * panGestureRecog = [NSString stringWithFormat:@"%@%@%@%@%@%@",@"UIScrollV", @"iewPanG", @"estur",@"eRecog",@"nize",@"r"];
        NSString * textTap = [NSString stringWithFormat:@"%@%@%@%@%@",@"UITe",@"xtTa",@"pReco",@"gniz",@"er"];
        // trigger touches
        if ([gestureRecognizer isKindOfClass:[WXTouchGestureRecognizer class]]) {
            return YES;
        }
        // swipe and scroll
        if ([gestureRecognizer isKindOfClass:[UISwipeGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:NSClassFromString(panGestureRecog)]) {
            return YES;
        }
        // onclick and textviewInput
        if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass: NSClassFromString(textTap)]) {
            return YES;
        }
        
        return NO;
    }
    
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
        if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] &&
            [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
            if (otherGestureRecognizer.state != UIGestureRecognizerStateFailed) {
                if ([gestureRecognizer view].wx_component != nil && [otherGestureRecognizer view].wx_component != nil) {
                    return YES;
                }
            }
        }
        
        return NO;
    }
    
    #pragma mark - Utils
    
    - (NSDictionary *)touchResultWithScreenLocation:(CGPoint)screenLocation pageLocation:(CGPoint)pageLocation identifier:(NSNumber *)identifier
    {
        NSMutableDictionary *resultTouch = [[NSMutableDictionary alloc] initWithCapacity:5];
        CGFloat scaleFactor = self.weexInstance.pixelScaleFactor;
        resultTouch[@"screenX"] = @(screenLocation.x/scaleFactor);
        resultTouch[@"screenY"] = @(screenLocation.y/scaleFactor);
        resultTouch[@"pageX"] = @(pageLocation.x/scaleFactor);
        resultTouch[@"pageY"] = @(pageLocation.y/scaleFactor);
        resultTouch[@"identifier"] = identifier;
        
        return resultTouch;
    }
    
    // find virtual component's root component
    - (WXComponent*)getRecycleListComponent
    {
        if ([self isKindOfClass:[WXRecycleListComponent class]]) {
            return self;
        }
        if ([self.ref isEqualToString:WX_SDK_ROOT_REF]) {
            return nil;
        }
        return [self.supercomponent getRecycleListComponent];
    }
    
    @end
    
    @implementation WXTouchGestureRecognizer
    {
        __weak WXComponent *_component;
        NSUInteger _touchIdentifier;
    }
    
    - (instancetype)initWithTarget:(id)target action:(SEL)action
    {
        return [self initWithComponent:nil];
    }
    
    - (instancetype)initWithComponent:(WXComponent *)component
    {
        if (self = [super initWithTarget:self action:@selector(touchResponse:)]) {
            _component = component;
            
            _listenTouchStart = NO;
            _listenTouchEnd = NO;
            _listenTouchMove = NO;
            _listenTouchCancel = NO;
            
            self.cancelsTouchesInView = NO;
        }
        
        return self;
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        [super touchesBegan:touches withEvent:event];
        
        if (_listenTouchStart) {
            [self fireTouchEvent:@"touchstart" withTouches:touches];
        }
        if(_listenPseudoTouch) {
            NSMutableDictionary *styles = [_component getPseudoClassStyles:@"active"];
            [_component updatePseudoClassStyles:styles];
        }
    
    }
    
    - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        [super touchesMoved:touches withEvent:event];
        
        if (_listenTouchMove) {
            [self fireTouchEvent:@"touchmove" withTouches:touches];
        }
    }
    
    - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        
        [super touchesEnded:touches withEvent:event];
        
        if (_listenTouchEnd) {
            [self fireTouchEvent:@"touchend" withTouches:touches];
        }
        if(_listenPseudoTouch) {
            [self recoveryPseudoStyles:_component.styles];
        }
    
    }
    
    - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        [super touchesCancelled:touches withEvent:event];
        
        if (_listenTouchCancel) {
            [self fireTouchEvent:@"touchcancel" withTouches:touches];
        }
        if(_listenPseudoTouch) {
            [self recoveryPseudoStyles:_component.styles];
        }
    }
    
    - (void)fireTouchEvent:(NSString *)eventName withTouches:(NSSet<UITouch *> *)touches
    {
        if (_component == nil) {
            return;
        }
        
        NSMutableArray *resultTouches = [NSMutableArray new];
        
        CGPoint accmOffset = CGPointZero;
        UIView* rootView = _component.weexInstance.rootView;
    //    UIView* view = self.view;
    //    while (view && view != rootView) {
    //        if ([view isKindOfClass:[UIScrollView class]]) {
    //            CGPoint offset = ((UIScrollView*)view).contentOffset;
    //            accmOffset.x += offset.x;
    //            accmOffset.y += offset.y;
    //        }
    //        view = view.superview;
    //    }
        
        for (UITouch *touch in touches) {
            CGPoint screenLocation = [touch locationInView:touch.window];
            CGPoint pageLocation = [touch locationInView:rootView];
            pageLocation.x += accmOffset.x;
            pageLocation.y += accmOffset.y;
          
            if (!touch.wx_identifier) {
                touch.wx_identifier = @(_touchIdentifier++);
            }
            NSDictionary *resultTouch = [_component touchResultWithScreenLocation:screenLocation pageLocation:pageLocation identifier:touch.wx_identifier];
            NSMutableDictionary * mutableResultTouch = [resultTouch mutableCopy];
            
            float value = touch.force*60;
            float maxValue = touch.maximumPossibleForce*60;
            if (touch.maximumPossibleForce) {
                // the forece value will be range 1 from 0.
                [mutableResultTouch setObject:[NSNumber numberWithFloat:value/maxValue] forKey:@"force"];
            }else {
                [mutableResultTouch setObject:[NSNumber numberWithFloat:0.0] forKey:@"force"];
            }
            
            if (mutableResultTouch) { // component is nil, mutableResultTouch will be nil
                [resultTouches addObject:mutableResultTouch];
            }
        }
        
        [_component fireEvent:eventName params:@{@"changedTouches":resultTouches ?: @[]}];
    }
    
    - (void)recoveryPseudoStyles:(NSDictionary *)styles
    {
        [_component recoveryPseudoStyles:styles];
    }
    
    - (void)touchResponse:(UIGestureRecognizer *)gesture
    {
        
    }
    
    @end

     weex中Vue设置空间样式,使用style=""、:style="{}"、class="" 三者是有一些区别的 使用中发现在一个负责一些的页面上 flex设置显示了三种不同的效果,其中class=""是期望的效果

  • 相关阅读:
    python基础学习1-函数相关
    python基础学习1-SET 集合
    Linux命令学习笔记1
    python基础学习1-字典的使用
    python基础学习1-列表使用
    Jzoj4743 积木
    Jzoj4786 小a的强迫症
    Jzoj4746 树塔狂想曲
    Jzoj5246 Trip
    Jzoj5245 Competing Souls
  • 原文地址:https://www.cnblogs.com/yuxiaoyiyou/p/14218224.html
Copyright © 2020-2023  润新知