Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
bellini666 opened this issue Nov 11, 2018 · 28 comments
Closed

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

bellini666 opened this issue Nov 11, 2018 · 28 comments

Comments

@bellini666
Copy link

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!

@SupriyaKalghatgi
Copy link
Contributor

Follow instructions as per issue template https://github.com/GeekyAnts/NativeBase/blob/master/ISSUE_TEMPLATE.txt

Failing which this issue will be closed today

@bellini666
Copy link
Author

Failing which this issue will be closed today

Even though all the information required is here, yes, I can adapt to your template if you prefer, just give me until tomorrow because I have no time to do that today

@andresmtz98
Copy link

Same issue :/

@suvenduchhatoi
Copy link
Contributor

suvenduchhatoi commented Dec 20, 2018

@bellini666 @andresmtz98
Where have you imported your Picker component from?
If you have imported it from "react-native", then it is already an issue with "react-native"...
If you have imported it from "native-base", Check if the issue doesn't persist after importing from "react-native", then we can check if the issue is exclusive to "native-base"
seems to be working fine in my example snippet
screenshot 2018-12-24 at 5 24 43 pm

@suvenduchhatoi
Copy link
Contributor

Closing the issue due to no response for a while...Hope your issue has been resolved.You can reopen the issue if you still feel the issue is exclusive to "native-base"...

@bellini666
Copy link
Author

bellini666 commented Dec 29, 2018

@suvenduchhatoi I tried using the one from "react-native" but it doesn't work like the one in android. I will display the picker itself, so the issue is for sure here.

If you take a look at the description I wrote a snipped of my component. If you take the renderButton away from it (that I wrote as a workaround for the issue) it should display the issue. try to add a long text in the placeholder (e.g. "blab lab bla bbla bla bla")

Note that my snipped also has an iosIcon in it

Can you reopen the issue? I don't have permission to do so

@bellini666
Copy link
Author

@suvenduchhatoi taking a look at nativebase's code I just notice this: https://github.com/GeekyAnts/NativeBase/blob/master/src/basic/Picker.ios.js

That component basically tries to mimic the one from android for the ios. The problem is for sure in it!

@bellini666
Copy link
Author

bellini666 commented Dec 29, 2018

@suvenduchhatoi I was able to reproduce the issue in a snack: https://snack.expo.io/B1HqvwrbE

The problem seems to happen when I add an iosIcon. If you remove it (and remove the renderIcon too) it will work just like you described

Here is a screenshot of it:

screenshot from 2018-12-29 19-38-14

Note that the text doesn't respect the size of the parent (the card) to ellipsize. It should also consider the fact that it has an icon. Like I commented, if you remove the renderIcon it will ellipsize in the right place

@bellini666
Copy link
Author

@suvenduchhatoi so, can you reopen the issue? Just want to confirm with you so I don't have to open a new one

@suvenduchhatoi suvenduchhatoi reopened this Jan 4, 2019
@ihusak
Copy link

ihusak commented Jan 10, 2019

the same issue in iOS... need help...

@suvenduchhatoi
Copy link
Contributor

Using style={{width:250}} within Button may be a fix at the moment. Yes, we will inspect why this is happening
fix at the moment using style for button inside picker

@SupriyaKalghatgi
Copy link
Contributor

Fixed with commit 460eddc

@bellini666
Copy link
Author

@SupriyaKalghatgi I just tested the latest release (that seems to include the fix above) and it doesn't seem to fix the issue.

@SupriyaKalghatgi
Copy link
Contributor

@bellini666 share package.json
did you try clearing cache once?

@bellini666
Copy link
Author

@SupriyaKalghatgi yes I did clear the cache. The app continues to look exactly like the screenshots from my first post: android works fine but long texts on iOS not ellipsize.

Here is my package.json:

  "name": "smartcheck",
  "version": "0.0.1",
  "private": true,
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "postinstall": "remotedev-debugger",
    "start": "expo start",
    "eject": "expo eject",
    "android": "expo android",
    "ios": "expo ios",
    "test": "find src -name \"*.js\" | xargs prettier-check --trailing-comma=all && eslint src --max-warnings=0",
    "lint": "eslint --fix src --max-warnings=0",
    "prettier": "find src -name \"*.js\" | xargs prettier --trailing-comma=all --write",
    "publish": "expo publish",
    "build-android": "expo build:android",
    "build-ios": "expo build:ios",
    "devtools": "react-devtools"
  },
  "dependencies": {
    "@babel/runtime": "^7.3.1",
    "@expo/vector-icons": "^9.0.0",
    "axios": "^0.18.0",
    "babel-preset-expo": "^5.0.0",
    "color": "^3.1.0",
    "expo": "32.0.6",
    "final-form": "^4.11.1",
    "jest-cli": "^24.1.0",
    "jwt-decode": "^2.2.0",
    "lodash": "^4.17.11",
    "moment": "^2.24.0",
    "moment-range": "^4.0.1",
    "moment-timezone": "^0.5.23",
    "native-base": "2.12.0",
    "react": "16.5.0",
    "react-final-form": "^4.0.2",
    "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.1.tar.gz",
    "react-native-action-button": "^2.8.5",
    "react-native-autogrow-textinput": "^5.2.0",
    "react-native-calculator": "^0.5.2",
    "react-native-calendars": "^1.22.0",
    "react-native-datepicker": "^1.7.2",
    "react-native-easy-grid": "^0.2.1",
    "react-native-masked-text": "^1.10.1",
    "react-native-modal": "^7.0.2",
    "react-native-step-indicator": "0.0.9",
    "react-native-tab-view": "^1.3.2",
    "react-navigation": "^3.3.0",
    "react-redux": "^6.0.1",
    "redux": "^4.0.1",
    "redux-persist": "5.10.0",
    "redux-persist-transform-filter": "^0.0.18",
    "redux-promise-middleware": "^5.1.1",
    "redux-sentry-middleware": "0.0.15",
    "redux-thunk": "^2.3.0",
    "remote-redux-devtools": "^0.5.16",
    "remote-redux-devtools-on-debugger": "^0.8.3",
    "sentry-expo": "^1.11.2",
    "ttag": "^1.7.1",
    "uuid": "^3.3.2"
  },
  "devDependencies": {
    "@babel/cli": "^7.2.3",
    "@babel/core": "^7.3.3",
    "@babel/plugin-proposal-class-properties": "^7.3.3",
    "@babel/plugin-proposal-decorators": "^7.3.0",
    "@babel/plugin-proposal-export-namespace-from": "^7.2.0",
    "@babel/plugin-proposal-function-sent": "^7.2.0",
    "@babel/plugin-proposal-json-strings": "^7.2.0",
    "@babel/plugin-proposal-numeric-separator": "^7.2.0",
    "@babel/plugin-proposal-object-rest-spread": "^7.3.2",
    "@babel/plugin-proposal-throw-expressions": "^7.2.0",
    "@babel/plugin-syntax-dynamic-import": "^7.2.0",
    "@babel/plugin-syntax-import-meta": "^7.2.0",
    "@babel/plugin-transform-flow-strip-types": "^7.2.3",
    "@babel/plugin-transform-runtime": "^7.2.0",
    "babel-eslint": "^10.0.1",
    "babel-plugin-transform-inline-environment-variables": "^0.4.3",
    "eslint": "^5.14.1",
    "eslint-plugin-import": "^2.16.0",
    "eslint-plugin-jsx-a11y": "^6.2.1",
    "eslint-plugin-prettier": "^3.0.1",
    "eslint-plugin-react": "^7.12.4",
    "eslint-plugin-react-native": "^3.6.0",
    "expo-cli": "^2.11.2",
    "fb-watchman": "^2.0.0",
    "jest": "^24.1.0",
    "jest-expo": "^32.0.0",
    "prettier": "^1.16.4",
    "prettier-check": "^2.0.0",
    "react-devtools": "^3.6.0",
    "schedule": "^0.4.0"
  }
}

@sb8244
Copy link

sb8244 commented Mar 7, 2019

V 2.12.0 adds an ellipses but still pushes the caret off screen:

image

SupriyaKalghatgi pushed a commit that referenced this issue Mar 8, 2019
@SupriyaKalghatgi
Copy link
Contributor

Fixed with commit e140084

@bellini666
Copy link
Author

Fixed with commit e140084

hrm, I just saw the commit and, although I think it will fix my issue (still need to test it when a new release is out), I think it will not work on some cases since it is considering the window width. If there are 2 pickers in the same line (meaning that each one has a size of ~ 1/2 of the device's width), it will have the same problem. Unless I'm missing something here.

Ah, and that would happen also even for the default case of one picker per line if the horizontal margins are greater than 50.

@itsakt
Copy link

itsakt commented Mar 15, 2019

Had same issue while placing 2 pickers in the same line (Grid->Row->(Col,Col)) . I fixed it by wrapping each picker inside Body

<Body style={{width:"90%"}}>
    <Picker/>
</Body>

Havn't checked the result on Android though.

@stephanschoenig
Copy link

Hi @SupriyaKalghatgi the fix to the Picker in 2.12.1 breaks my screen and I had to downgrade back to version 2.11.0 as I could not find out how to fix the layout issue. I use a Picker inside a DeckSwiper and version 2.12.1 makes the Picker wider than the DeckSwipper width and once a value is selected it, the formatting becomes completely skewed (the trick from @itsakt <Body style={{width:"90%"}}>... did not work for me):

Version 2.12.1, the icon (orange) is behind the DeckSwiper to the right-hand side:
v2 12 1 before selection

Version 2.12.1 once a value is selected:
v2 12 1 after selection

The same in version 2.11.0, which is perfect:
v2 11 0 after selection

@bellini666
Copy link
Author

The issue @mindfulnessforever had is probably related to my previous coment

@Makar8000
Copy link

Hi @SupriyaKalghatgi the fix to the Picker in 2.12.1 breaks my screen and I had to downgrade back to version 2.11.0 as I could not find out how to fix the layout issue. I use a Picker inside a DeckSwiper and version 2.12.1 makes the Picker wider than the DeckSwipper width and once a value is selected it, the formatting becomes completely skewed (the trick from @itsakt <Body style={{width:"90%"}}>... did not work for me):

Version 2.12.1, the icon (orange) is behind the DeckSwiper to the right-hand side:
v2 12 1 before selection

This seems to be related to #2630

@bnash2501
Copy link

bnash2501 commented Apr 29, 2019

I'm having a similar issue. If you are using inline labels for your pickers, the picker values will lay on top of the picker label. And there really isn't a good way to fix this due to:
<Text style={[this.props.textStyle, { width: Dimensions.get("window").width - 50 }]} note={this.props.note} numberOfLines={1} ellipsizeMode="tail">
There is now no control over the pickers width. We've had to downgrade to 2.12.0 due to this regression.

@pearpai
Copy link

pearpai commented May 10, 2019

@bnash2501 may like this we need
<Text style={[ { width: Dimensions.get("window").width - 50 }, this.props.textStyle]} note={this.props.note} numberOfLines={1} ellipsizeMode="tail">

We've had to downgrade to 2.12.0 due to this regression too!

@bnash2501
Copy link

@SupriyaKalghatgi Can we get this reopened? This is the PR that broke the pickers: e140084
As pearpai has pointed out, the width should be the first style property so it can be overwritten. Not everyone uses full width pickers.

@xfyre
Copy link

xfyre commented Jun 22, 2019

I'm having the same issue on iOS. Is there a chance to get this fixed?

@Rajdeepc
Copy link

Rajdeepc commented Sep 13, 2019

Why this is closed? The issue is still there in "native-base": "^2.12.1".

@fmukendi
Copy link

adding {flexShrink:1} to the bubble works perfect with me !!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests