From 7adc0bda28ab46c79042f02392763b08efc628c0 Mon Sep 17 00:00:00 2001 From: wqyfavor Date: Tue, 6 Nov 2018 15:21:04 +0800 Subject: [PATCH] [iOS] Do not layout if non css style is updated such as 'transform' by updateStyle. (#1717) --- .../Sources/Layout/WXComponent+Layout.mm | 309 ++++++++++-------- 1 file changed, 171 insertions(+), 138 deletions(-) diff --git a/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.mm b/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.mm index aa3618ba3c..18cb24dbb1 100644 --- a/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.mm +++ b/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.mm @@ -184,147 +184,180 @@ - (void)_fillCSSNode:(NSDictionary *)styles isUpdate:(BOOL)isUpdate return; } - // flex - if (styles[@"flex"]) { - _flexCssNode->set_flex([WXConvert CGFloat:styles[@"flex"]]); - } - if (isnan(_flexCssNode->getFlex())) { - // to make the default flex value is zero, yoga is nan, maybe this can configured by yoga config - _flexCssNode->set_flex(0); - } - - if (styles[@"flexDirection"]) { - _flexCssNode->setFlexDirection([self fxFlexDirection:styles[@"flexDirection"]], isUpdate); - } - if (styles[@"alignItems"]) { - _flexCssNode->setAlignItems([self fxAlign:styles[@"alignItems"]]); - } - if (styles[@"alignSelf"]) { - _flexCssNode->setAlignSelf([self fxAlignSelf:styles[@"alignSelf"]]); - } - if (styles[@"flexWrap"]) { - _flexCssNode->setFlexWrap([self fxWrap:styles[@"flexWrap"]]); - } - if (styles[@"justifyContent"]) { - _flexCssNode->setJustifyContent([self fxJustify:styles[@"justifyContent"]]); - } - - // position - if (styles[@"position"]) { - _flexCssNode->setStylePositionType([self fxPositionType:styles[@"position"]]); - } - if (styles[@"top"]) { - _flexCssNode->setStylePosition(WeexCore::kPositionEdgeTop, - [self judgePropValuePropValue:styles[@"top"] defaultValue:NAN]); - } - if (styles[@"left"]) { - _flexCssNode->setStylePosition(WeexCore::kPositionEdgeLeft, - [self judgePropValuePropValue:styles[@"left"] defaultValue:NAN]); - } - if(styles[@"right"]) { - _flexCssNode->setStylePosition(WeexCore::kPositionEdgeRight, - [self judgePropValuePropValue:styles[@"right"] defaultValue:NAN]); - } - if (styles[@"bottom"]) { - _flexCssNode->setStylePosition(WeexCore::kPositionEdgeBottom, - [self judgePropValuePropValue:styles[@"bottom"] defaultValue:NAN]); - } - - // dimension - if (styles[@"width"]) { - _flexCssNode->setStyleWidth([self judgePropValuePropValue:styles[@"width"] defaultValue:NAN] - ,isUpdate); - } - if (styles[@"height"]) { - _flexCssNode->setStyleHeight([self judgePropValuePropValue:styles[@"height"] defaultValue:NAN]); - } - if (styles[@"minWidth"]) { - _flexCssNode->setMinWidth([self judgePropValuePropValue:styles[@"minWidth"] defaultValue:NAN] - ,isUpdate); - } - if (styles[@"minHeight"]) { - _flexCssNode->setMinHeight([self judgePropValuePropValue:styles[@"minHeight"] defaultValue:NAN]); - } - if (styles[@"maxWidth"]) { - _flexCssNode->setMaxWidth([self judgePropValuePropValue:styles[@"maxWidth"] defaultValue:NAN] - ,isUpdate); - } - if (styles[@"maxHeight"]) { - _flexCssNode->setMaxHeight([self judgePropValuePropValue:styles[@"maxHeight"] defaultValue:NAN]); - } - - // margin - if (styles[@"margin"]) { - _flexCssNode->setMargin(WeexCore::kMarginALL, - [self judgePropValuePropValue:styles[@"margin"] defaultValue:0]); - } - if (styles[@"marginTop"]) { - _flexCssNode->setMargin(WeexCore::kMarginTop, - [self judgePropValuePropValue:styles[@"marginTop"] defaultValue:0]); - } - if (styles[@"marginBottom"]) { - _flexCssNode->setMargin(WeexCore::kMarginBottom, - [self judgePropValuePropValue:styles[@"marginBottom"] defaultValue:0]); - } - if (styles[@"marginRight"]) { - _flexCssNode->setMargin(WeexCore::kMarginRight, - [self judgePropValuePropValue:styles[@"marginRight"] defaultValue:0]); - } - if (styles[@"marginLeft"]) { - _flexCssNode->setMargin(WeexCore::kMarginLeft, - [self judgePropValuePropValue:styles[@"marginLeft"] defaultValue:0]); - } - - // border - if (styles[@"borderWidth"]) { - _flexCssNode->setBorderWidth(WeexCore::kBorderWidthALL, - [self judgePropValuePropValue:styles[@"borderWidth"] defaultValue:0]); - } - if (styles[@"borderTopWidth"]) { - _flexCssNode->setBorderWidth(WeexCore::kBorderWidthTop, - [self judgePropValuePropValue:styles[@"borderTopWidth"] defaultValue:0]); - } - - if (styles[@"borderLeftWidth"]) { - _flexCssNode->setBorderWidth(WeexCore::kBorderWidthLeft, - [self judgePropValuePropValue:styles[@"borderLeftWidth"] defaultValue:0]); - } - - if (styles[@"borderBottomWidth"]) { - _flexCssNode->setBorderWidth(WeexCore::kBorderWidthBottom, - [self judgePropValuePropValue:styles[@"borderBottomWidth"] defaultValue:0]); - } - if (styles[@"borderRightWidth"]) { - _flexCssNode->setBorderWidth(WeexCore::kBorderWidthRight, - [self judgePropValuePropValue:styles[@"borderRightWidth"] defaultValue:0]); - } - - // padding - if (styles[@"padding"]) { - _flexCssNode->setPadding(WeexCore::kPaddingALL, - [self judgePropValuePropValue:styles[@"padding"] defaultValue:0]); - } - if (styles[@"paddingTop"]) { - _flexCssNode->setPadding(WeexCore::kPaddingTop, - [self judgePropValuePropValue:styles[@"paddingTop"] defaultValue:0]); - } - if (styles[@"paddingLeft"]) { - _flexCssNode->setPadding(WeexCore::kPaddingLeft, - [self judgePropValuePropValue:styles[@"paddingLeft"] defaultValue:0]); - } - if (styles[@"paddingBottom"]) { - _flexCssNode->setPadding(WeexCore::kPaddingBottom, - [self judgePropValuePropValue:styles[@"paddingBottom"] defaultValue:0]); - } - if (styles[@"paddingRight"]) { - _flexCssNode->setPadding(WeexCore::kPaddingRight, - [self judgePropValuePropValue:styles[@"paddingRight"] defaultValue:0]); - } - + BOOL needLayout = NO; + + // flex + if (styles[@"flex"]) { + _flexCssNode->set_flex([WXConvert CGFloat:styles[@"flex"]]); + needLayout = YES; + } + if (isnan(_flexCssNode->getFlex())) { + // to make the default flex value is zero, yoga is nan, maybe this can configured by yoga config + _flexCssNode->set_flex(0); + needLayout = YES; + } + + if (styles[@"flexDirection"]) { + _flexCssNode->setFlexDirection([self fxFlexDirection:styles[@"flexDirection"]], isUpdate); + needLayout = YES; + } + if (styles[@"alignItems"]) { + _flexCssNode->setAlignItems([self fxAlign:styles[@"alignItems"]]); + needLayout = YES; + } + if (styles[@"alignSelf"]) { + _flexCssNode->setAlignSelf([self fxAlignSelf:styles[@"alignSelf"]]); + needLayout = YES; + } + if (styles[@"flexWrap"]) { + _flexCssNode->setFlexWrap([self fxWrap:styles[@"flexWrap"]]); + needLayout = YES; + } + if (styles[@"justifyContent"]) { + _flexCssNode->setJustifyContent([self fxJustify:styles[@"justifyContent"]]); + needLayout = YES; + } + + // position + if (styles[@"position"]) { + _flexCssNode->setStylePositionType([self fxPositionType:styles[@"position"]]); + needLayout = YES; + } + if (styles[@"top"]) { + _flexCssNode->setStylePosition(WeexCore::kPositionEdgeTop, + [self judgePropValuePropValue:styles[@"top"] defaultValue:NAN]); + needLayout = YES; + } + if (styles[@"left"]) { + _flexCssNode->setStylePosition(WeexCore::kPositionEdgeLeft, + [self judgePropValuePropValue:styles[@"left"] defaultValue:NAN]); + needLayout = YES; + } + if(styles[@"right"]) { + _flexCssNode->setStylePosition(WeexCore::kPositionEdgeRight, + [self judgePropValuePropValue:styles[@"right"] defaultValue:NAN]); + needLayout = YES; + } + if (styles[@"bottom"]) { + _flexCssNode->setStylePosition(WeexCore::kPositionEdgeBottom, + [self judgePropValuePropValue:styles[@"bottom"] defaultValue:NAN]); + needLayout = YES; + } + + // dimension + if (styles[@"width"]) { + _flexCssNode->setStyleWidth([self judgePropValuePropValue:styles[@"width"] defaultValue:NAN], isUpdate); + needLayout = YES; + } + if (styles[@"height"]) { + _flexCssNode->setStyleHeight([self judgePropValuePropValue:styles[@"height"] defaultValue:NAN]); + needLayout = YES; + } + if (styles[@"minWidth"]) { + _flexCssNode->setMinWidth([self judgePropValuePropValue:styles[@"minWidth"] defaultValue:NAN], isUpdate); + needLayout = YES; + } + if (styles[@"minHeight"]) { + _flexCssNode->setMinHeight([self judgePropValuePropValue:styles[@"minHeight"] defaultValue:NAN]); + needLayout = YES; + } + if (styles[@"maxWidth"]) { + _flexCssNode->setMaxWidth([self judgePropValuePropValue:styles[@"maxWidth"] defaultValue:NAN], isUpdate); + needLayout = YES; + } + if (styles[@"maxHeight"]) { + _flexCssNode->setMaxHeight([self judgePropValuePropValue:styles[@"maxHeight"] defaultValue:NAN]); + needLayout = YES; + } + + // margin + if (styles[@"margin"]) { + _flexCssNode->setMargin(WeexCore::kMarginALL, + [self judgePropValuePropValue:styles[@"margin"] defaultValue:0]); + needLayout = YES; + } + if (styles[@"marginTop"]) { + _flexCssNode->setMargin(WeexCore::kMarginTop, + [self judgePropValuePropValue:styles[@"marginTop"] defaultValue:0]); + needLayout = YES; + } + if (styles[@"marginBottom"]) { + _flexCssNode->setMargin(WeexCore::kMarginBottom, + [self judgePropValuePropValue:styles[@"marginBottom"] defaultValue:0]); + needLayout = YES; + } + if (styles[@"marginRight"]) { + _flexCssNode->setMargin(WeexCore::kMarginRight, + [self judgePropValuePropValue:styles[@"marginRight"] defaultValue:0]); + } + if (styles[@"marginLeft"]) { + _flexCssNode->setMargin(WeexCore::kMarginLeft, + [self judgePropValuePropValue:styles[@"marginLeft"] defaultValue:0]); + needLayout = YES; + } + + // border + if (styles[@"borderWidth"]) { + _flexCssNode->setBorderWidth(WeexCore::kBorderWidthALL, + [self judgePropValuePropValue:styles[@"borderWidth"] defaultValue:0]); + needLayout = YES; + } + if (styles[@"borderTopWidth"]) { + _flexCssNode->setBorderWidth(WeexCore::kBorderWidthTop, + [self judgePropValuePropValue:styles[@"borderTopWidth"] defaultValue:0]); + needLayout = YES; + } + + if (styles[@"borderLeftWidth"]) { + _flexCssNode->setBorderWidth(WeexCore::kBorderWidthLeft, + [self judgePropValuePropValue:styles[@"borderLeftWidth"] defaultValue:0]); + needLayout = YES; + } + + if (styles[@"borderBottomWidth"]) { + _flexCssNode->setBorderWidth(WeexCore::kBorderWidthBottom, + [self judgePropValuePropValue:styles[@"borderBottomWidth"] defaultValue:0]); + needLayout = YES; + } + if (styles[@"borderRightWidth"]) { + _flexCssNode->setBorderWidth(WeexCore::kBorderWidthRight, + [self judgePropValuePropValue:styles[@"borderRightWidth"] defaultValue:0]); + needLayout = YES; + } + + // padding + if (styles[@"padding"]) { + _flexCssNode->setPadding(WeexCore::kPaddingALL, + [self judgePropValuePropValue:styles[@"padding"] defaultValue:0]); + needLayout = YES; + } + if (styles[@"paddingTop"]) { + _flexCssNode->setPadding(WeexCore::kPaddingTop, + [self judgePropValuePropValue:styles[@"paddingTop"] defaultValue:0]); + needLayout = YES; + } + if (styles[@"paddingLeft"]) { + _flexCssNode->setPadding(WeexCore::kPaddingLeft, + [self judgePropValuePropValue:styles[@"paddingLeft"] defaultValue:0]); + needLayout = YES; + } + if (styles[@"paddingBottom"]) { + _flexCssNode->setPadding(WeexCore::kPaddingBottom, + [self judgePropValuePropValue:styles[@"paddingBottom"] defaultValue:0]); + needLayout = YES; + } + if (styles[@"paddingRight"]) { + _flexCssNode->setPadding(WeexCore::kPaddingRight, + [self judgePropValuePropValue:styles[@"paddingRight"] defaultValue:0]); + needLayout = YES; + } + + if (needLayout) { [self setNeedsLayout]; + } } --(CGFloat)judgePropValuePropValue:(id)propValue defaultValue:(CGFloat)defaultValue +- (CGFloat)judgePropValuePropValue:(id)propValue defaultValue:(CGFloat)defaultValue { CGFloat convertValue = (CGFloat)[WXConvert WXFlexPixelType:propValue scaleFactor:self.weexInstance.pixelScaleFactor]; if (!isnan(convertValue)) {