Skip to content

Picker on iOS doesn't ellipsize its text when an overflow happens #2431

Closed
@bellini666

Description

Here is something I'm struggling to find a solution. I have a picker inside a form in my app, but when the text inside it is too big it won't ellipsize on iOS. For example, this view on android:

screenshot_20181111-150016

Is displayed like this on iOS:

whatsapp image 2018-11-08 at 20 06 22

That is the issue in question! Bellow I'll describe something that I have done to try to workaround the problem and is presenting even another issue

====

After playing a lot with flex and widths I decided to try to override the renderButton prop and force the ellipsize by hand by setting a width in it. Here is my component as it is right now:

export default class PickerInput extends React.Component {
  state = {
    itemWidth: styles.deviceWidth * 0.85,
    labelWidth: 0,
  };

  render() {
    const { label, children, selectedValue, ...other } = this.props;
    const style = {
      flex: 1,
    };
    if (!selectedValue && styles.OS === "android") {
      style.color = "rgba(51, 51, 51, .20)";
    }
    return (
      <Item
        picker
        style={{
          marginTop: 0,
        }}
        onLayout={e => this.setState({ itemWidth: e.nativeEvent.layout.width })}
      >
        {styles.OS === "android" || this.state.labelWidth ? (
          <Label>{label}</Label>
        ) : (
          <View
            onLayout={e =>
              this.setState({ labelWidth: e.nativeEvent.layout.width })
            }
          >
            <Label>{label}</Label>
          </View>
        )}
        <Picker
          mode="dialog"
          placeholderStyle={{ color: "#bfc6ea" }}
          iosHeader={this.props.label}
          iosIcon={
            <Icon name="ios-arrow-down" style={styles.styles.colorGray} />
          }
          renderButton={buttonProps => {
            // This only affects iOS. Copied from native-base's Picker.ios.js
            const { onPress, text, picker, selectedItem } = buttonProps;
            const textStyle = [picker.props.textStyle];
            if (!selectedItem) {
              textStyle.push(picker.props.placeholderStyle);
            }
            let width = this.state.itemWidth - this.state.labelWidth;
            // Give some border
            width -= styles.theme.isIphoneX ? 55 : 25;

            return (
              <Button
                dark
                picker
                transparent
                onPress={onPress}
                style={{
                  justifyContent: "flex-start",
                  width: Math.max(5, width),
                }}
              >
                <Text
                  numberOfLines={1}
                  ellipsizeMode="tail"
                  style={textStyle}
                  note={picker.props.note}
                >
                  {text}
                </Text>
                {picker.renderIcon()}
              </Button>
            );
          }}
          selectedValue={selectedValue}
          style={style}
          {...other}
        >
          {children}
        </Picker>
      </Item>
    );
  }
}

As you can see, I wait until the item and the label are rendered, get their width and set the width of them button as the difference between the 2. It works (not perfect, but works around the issue), but then I have this difference between an iPhone 6 and an iPhone X (tested on appetize.io):

iPhone 6:
2018-11-11 13-11-07 screenshot

iPhone X:
2018-11-11 13-14-07 screenshot

So, even though the solution is working nicely (again, as a work around) on iPhone 6, the same fix on iPhone X made the item itself overflows (even though I'm giving even more border for it).

So, like I said in the beginning, the main issue issue here is the lack of ellipsize in the picker provided by native-base. If it is solved, my issues with my workaround won't matter. If you prefer that I describe something more or even open another issue for something not related here (e.g. the difference between iPhone X and iPhone 6) just ask!

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions