mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-26 22:00:17 +08:00
Implement custom measure for ios btn when textWrap is true (#4326)
Implement custom measure for ios btn when textWrap is true
This commit is contained in:

committed by
GitHub

parent
014e7a8e0f
commit
e33eca63d6
28
apps/app/ui-tests-app/issues/issue-4287.xml
Normal file
28
apps/app/ui-tests-app/issues/issue-4287.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
|
||||||
|
<GridLayout columns="auto * auto" rows="auto *" borderWidth="1" borderColor="black">
|
||||||
|
|
||||||
|
<StackLayout borderWidth="1" borderColor="black" verticalAlignment="top" width="150">
|
||||||
|
<Label text="textWrap: false" horizontalAlignment="center"/>
|
||||||
|
|
||||||
|
<Button textWrap="false" backgroundColor="lightgreen" horizontalAlignment="left" text="1 2 3"/>
|
||||||
|
<Button textWrap="false" backgroundColor="lightblue" horizontalAlignment="left" text="1 2 3" style="padding: 5"/>
|
||||||
|
<Button textWrap="false" backgroundColor="lightgreen" horizontalAlignment="left" text="1 2 3" style="padding: 10; border-width: 10; border-color: blue;"/>
|
||||||
|
|
||||||
|
<Button textWrap="false" backgroundColor="lightblue" horizontalAlignment="left" text="1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6"/>
|
||||||
|
<Button textWrap="false" backgroundColor="lightgreen" horizontalAlignment="left" text="1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6" style="padding: 5"/>
|
||||||
|
<Button textWrap="false" backgroundColor="lightblue" horizontalAlignment="left" text="1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6" style="padding: 10; border-width: 10; border-color: blue;"/>
|
||||||
|
</StackLayout>
|
||||||
|
|
||||||
|
<StackLayout col="2" borderWidth="1" borderColor="black" verticalAlignment="top" width="150">
|
||||||
|
<Label text="textWrap: true" horizontalAlignment="center" />
|
||||||
|
|
||||||
|
<Button textWrap="true" backgroundColor="lightgreen" horizontalAlignment="left" text="1 2 3"/>
|
||||||
|
<Button textWrap="true" backgroundColor="lightblue" horizontalAlignment="left" text="1 2 3" style="padding: 5"/>
|
||||||
|
<Button textWrap="true" backgroundColor="lightgreen" horizontalAlignment="left" text="1 2 3" style="padding: 10; border-width: 10; border-color: blue;"/>
|
||||||
|
|
||||||
|
<Button textWrap="true" backgroundColor="lightblue" horizontalAlignment="left" text="1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6"/>
|
||||||
|
<Button textWrap="true" backgroundColor="lightgreen" horizontalAlignment="left" text="1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6" style="padding: 5"/>
|
||||||
|
<Button textWrap="true" backgroundColor="lightblue" horizontalAlignment="left" text="1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6" style="padding: 10; border-width: 10; border-color: blue;"/>
|
||||||
|
</StackLayout>
|
||||||
|
</GridLayout>
|
||||||
|
</Page>
|
@ -24,6 +24,7 @@ export function loadExamples() {
|
|||||||
examples.set("1657-ios", "issues/issue-1657-ios");
|
examples.set("1657-ios", "issues/issue-1657-ios");
|
||||||
examples.set("tabview-with-scrollview_4022","issues/tabview-with-scrollview_4022");
|
examples.set("tabview-with-scrollview_4022","issues/tabview-with-scrollview_4022");
|
||||||
examples.set("3354-ios", "issues/issue-3354");
|
examples.set("3354-ios", "issues/issue-3354");
|
||||||
|
examples.set("4287", "issues/issue-4287");
|
||||||
|
|
||||||
return examples;
|
return examples;
|
||||||
}
|
}
|
@ -18,7 +18,7 @@
|
|||||||
<!-- Wrap excessive items on new lines -->
|
<!-- Wrap excessive items on new lines -->
|
||||||
<FlexboxLayout flexWrap="wrap" alignContent="flex-start">
|
<FlexboxLayout flexWrap="wrap" alignContent="flex-start">
|
||||||
|
|
||||||
<Label textWrap="wrap" text="Sed aliquet diam sed augue vestibulum scelerisque." id="title" />
|
<Label textWrap="true" text="Sed aliquet diam sed augue vestibulum scelerisque." id="title" />
|
||||||
|
|
||||||
<!-- Use flexWrapBefore to control explicit line wrapping -->
|
<!-- Use flexWrapBefore to control explicit line wrapping -->
|
||||||
<Label text="Gihub issue labels:" flexWrapBefore="true" fontSize="11" />
|
<Label text="Gihub issue labels:" flexWrapBefore="true" fontSize="11" />
|
||||||
@ -33,7 +33,7 @@
|
|||||||
<Label text="T: Phasellus" borderRadius="5" backgroundColor="green" margin="2"/>
|
<Label text="T: Phasellus" borderRadius="5" backgroundColor="green" margin="2"/>
|
||||||
<Label text="Nullam" borderRadius="5" backgroundColor="gray" margin="2"/>
|
<Label text="Nullam" borderRadius="5" backgroundColor="gray" margin="2"/>
|
||||||
|
|
||||||
<Label flexWrapBefore="true" textWrap="wrap" text="Pellentesque molestie nibh et leo facilisis gravida ac porttitor eros. Etiam tempus diam nulla, ut fermentum mauris aliquet quis. Cras finibus vitae magna in bibendum." id="description" />
|
<Label flexWrapBefore="true" textWrap="true" text="Pellentesque molestie nibh et leo facilisis gravida ac porttitor eros. Etiam tempus diam nulla, ut fermentum mauris aliquet quis. Cras finibus vitae magna in bibendum." id="description" />
|
||||||
</FlexboxLayout>
|
</FlexboxLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<FlexboxLayout>
|
<FlexboxLayout>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Button as ButtonDefinition } from ".";
|
import { Button as ButtonDefinition } from ".";
|
||||||
import { TextBase } from "../text-base";
|
import { TextBase, booleanConverter } from "../text-base";
|
||||||
|
|
||||||
export * from "../text-base";
|
export * from "../text-base";
|
||||||
|
|
||||||
@ -10,6 +10,10 @@ export abstract class ButtonBase extends TextBase implements ButtonDefinition {
|
|||||||
return this.style.whiteSpace === "normal";
|
return this.style.whiteSpace === "normal";
|
||||||
}
|
}
|
||||||
set textWrap(value: boolean) {
|
set textWrap(value: boolean) {
|
||||||
|
if (typeof value === "string") {
|
||||||
|
value = booleanConverter(value)
|
||||||
|
}
|
||||||
|
|
||||||
this.style.whiteSpace = value ? "normal" : "nowrap";
|
this.style.whiteSpace = value ? "normal" : "nowrap";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
ButtonBase, PseudoClassHandler, Length, layout,
|
ButtonBase, PseudoClassHandler, Length, layout,
|
||||||
borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty,
|
borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty,
|
||||||
paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty,
|
paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty,
|
||||||
whiteSpaceProperty, WhiteSpace, textAlignmentProperty, TextAlignment
|
whiteSpaceProperty, WhiteSpace, textAlignmentProperty, TextAlignment, View
|
||||||
} from "./button-common";
|
} from "./button-common";
|
||||||
|
|
||||||
export * from "./button-common";
|
export * from "./button-common";
|
||||||
@ -145,19 +145,19 @@ export class Button extends ButtonBase {
|
|||||||
|
|
||||||
[textAlignmentProperty.setNative](value: TextAlignment) {
|
[textAlignmentProperty.setNative](value: TextAlignment) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case "left":
|
case "left":
|
||||||
this.nativeView.titleLabel.textAlignment = NSTextAlignment.Left;
|
this.nativeView.titleLabel.textAlignment = NSTextAlignment.Left;
|
||||||
this.nativeView.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left;
|
this.nativeView.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left;
|
||||||
break;
|
break;
|
||||||
case "initial":
|
case "initial":
|
||||||
case "center":
|
case "center":
|
||||||
this.nativeView.titleLabel.textAlignment = NSTextAlignment.Center;
|
this.nativeView.titleLabel.textAlignment = NSTextAlignment.Center;
|
||||||
this.nativeView.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Center;
|
this.nativeView.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Center;
|
||||||
break;
|
break;
|
||||||
case "right":
|
case "right":
|
||||||
this.nativeView.titleLabel.textAlignment = NSTextAlignment.Right;
|
this.nativeView.titleLabel.textAlignment = NSTextAlignment.Right;
|
||||||
this.nativeView.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Right;
|
this.nativeView.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Right;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,6 +175,46 @@ export class Button extends ButtonBase {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
||||||
|
// If there is text-wrap UIButton.sizeThatFits will return wrong result (not respecting the text wrap).
|
||||||
|
// So fallback to original onMeasure if there is no text-wrap and use custom measure otherwise.
|
||||||
|
if (!this.textWrap) {
|
||||||
|
return super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||||
|
}
|
||||||
|
|
||||||
|
let nativeView = this.nativeView;
|
||||||
|
if (nativeView) {
|
||||||
|
const width = layout.getMeasureSpecSize(widthMeasureSpec);
|
||||||
|
const widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
|
||||||
|
const height = layout.getMeasureSpecSize(heightMeasureSpec);
|
||||||
|
const heightMode = layout.getMeasureSpecMode(heightMeasureSpec);
|
||||||
|
|
||||||
|
const horizontalPadding = this.effectivePaddingLeft + this.effectiveBorderLeftWidth + this.effectivePaddingRight + this.effectiveBorderRightWidth;
|
||||||
|
let verticalPadding = this.effectivePaddingTop + this.effectiveBorderTopWidth + this.effectivePaddingBottom + this.effectiveBorderBottomWidth;
|
||||||
|
|
||||||
|
// The default button padding for UIButton - 6dip top and bottom.
|
||||||
|
if (verticalPadding === 0) {
|
||||||
|
verticalPadding = layout.toDevicePixels(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
const desiredSize = layout.measureNativeView(
|
||||||
|
nativeView.titleLabel,
|
||||||
|
width - horizontalPadding, widthMode,
|
||||||
|
height - verticalPadding, heightMode);
|
||||||
|
|
||||||
|
desiredSize.width = desiredSize.width + horizontalPadding;
|
||||||
|
desiredSize.height = desiredSize.height + verticalPadding;
|
||||||
|
|
||||||
|
const measureWidth = Math.max(desiredSize.width, this.effectiveMinWidth);
|
||||||
|
const measureHeight = Math.max(desiredSize.height, this.effectiveMinHeight);
|
||||||
|
|
||||||
|
const widthAndState = View.resolveSizeAndState(measureWidth, width, widthMode, 0);
|
||||||
|
const heightAndState = View.resolveSizeAndState(measureHeight, height, heightMode, 0);
|
||||||
|
|
||||||
|
this.setMeasuredDimension(widthAndState, heightAndState);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TapHandlerImpl extends NSObject {
|
class TapHandlerImpl extends NSObject {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Label as LabelDefinition } from ".";
|
import { Label as LabelDefinition } from ".";
|
||||||
import { TextBase, WhiteSpace, whiteSpaceProperty } from "../text-base";
|
import { TextBase, WhiteSpace, whiteSpaceProperty, booleanConverter } from "../text-base";
|
||||||
import { profile } from "../../profiling";
|
import { profile } from "../../profiling";
|
||||||
|
|
||||||
export * from "../text-base";
|
export * from "../text-base";
|
||||||
@ -13,6 +13,10 @@ export class Label extends TextBase implements LabelDefinition {
|
|||||||
return this.style.whiteSpace === "normal";
|
return this.style.whiteSpace === "normal";
|
||||||
}
|
}
|
||||||
set textWrap(value: boolean) {
|
set textWrap(value: boolean) {
|
||||||
|
if (typeof value === "string") {
|
||||||
|
value = booleanConverter(value)
|
||||||
|
}
|
||||||
|
|
||||||
this.style.whiteSpace = value ? "normal" : "nowrap";
|
this.style.whiteSpace = value ? "normal" : "nowrap";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import {
|
|||||||
TextBase, View, layout,
|
TextBase, View, layout,
|
||||||
borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty,
|
borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty,
|
||||||
paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty, whiteSpaceProperty,
|
paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty, whiteSpaceProperty,
|
||||||
Length, WhiteSpace
|
Length, WhiteSpace, booleanConverter
|
||||||
} from "../text-base";
|
} from "../text-base";
|
||||||
|
|
||||||
import { ios } from "../styling/background";
|
import { ios } from "../styling/background";
|
||||||
@ -37,6 +37,10 @@ export class Label extends TextBase implements LabelDefinition {
|
|||||||
return this.style.whiteSpace === "normal";
|
return this.style.whiteSpace === "normal";
|
||||||
}
|
}
|
||||||
set textWrap(value: boolean) {
|
set textWrap(value: boolean) {
|
||||||
|
if (typeof value === "string") {
|
||||||
|
value = booleanConverter(value)
|
||||||
|
}
|
||||||
|
|
||||||
this.style.whiteSpace = value ? "normal" : "nowrap";
|
this.style.whiteSpace = value ? "normal" : "nowrap";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user