grahammendick / navigation

Scene-Based Navigation for React and React Native
https://grahammendick.github.io/navigation/
Apache License 2.0
594 stars 41 forks source link

[iOS][Android]: Support custom component for TabBarItem #501

Closed cloudrco closed 3 years ago

cloudrco commented 3 years ago

Currently, the TabBarItem only receives an image prop. I would love to have a custom component, such as an SVG icon or custom view, as oppose to an image. Is there any workaround on how this can be implemented?

Depending if this will be supported, here are some suggestions/examples

<TabBarItem title="..." badge={3} icon={() => <CustomIcon />} />

<TabBarItem
  options={{
    title: "...",
    badge: 3,
    ....,
    icon: ({active}: Props) => active ? <IconActive /> : <Icon />
  }}
/>
grahammendick commented 3 years ago

Thanks for asking the question. We already had a bit of a chat about it. I mentioned that the aim of the Navigation router is to wrap the underlying native behaviour. Every component in the Navigation router renders to a native component. For example, the TabBar renders to the UITabBarController on iOS. So if the behaviour isn’t provided by the native component then the Navigation router won’t provide it. The UITabBarController doesn’t allow a custom view for tab content. It only allows images so the Navgation router can’t support an svg icon prop on the TabBarItem.

You can convert your svg’s to images and then they’ll work fine. Then you’ll get all the benefits of using the native iOS tab bar component. The look and feel will be identical to all other native apps. It will have all the built in features too, like double tapping a tab to navigate to the initial scene.

But, if view customisation is more important to you than using the native tab bar then the Navigation router still has your back. You can use any 3rd party TaBar component with the Navigation router, for example, the React Native Tab View. You can even have a separate stack per tab (as is standard on iOS).

cloudrco commented 3 years ago

Thanks for that detailed explanation @grahammendick. I guess I'm just used to having customized components (specifically in regards to design). It's just a bummer to see how native has such limitation 😞 . But now, I understand how this feature won't work. Thanks for the clarification 👍

grahammendick commented 3 years ago

I'll close this but if you have any further questions then add a comment and I'll get back to you

vbylen commented 2 years ago

Hey @grahammendick,

Is adding more systemItem icons something you would consider?

I'm using the image prop on <TabBarItem/>, but it looks blurry.

grahammendick commented 2 years ago

Hey @10000multiplier. Thanks for trying out the Navigation router. I told you you wouldn’t regret it. The TabBar already supports all 12 of the in-built UITabBarSystemItems on iOS. Or are you talking about something else, like SF Symbols on iOS 13, perhaps?

vbylen commented 2 years ago

Hey @10000multiplier. Thanks for trying out the Navigation router. I told you you wouldn’t regret it. The TabBar already supports all 12 of the in-built UITabBarSystemItems on iOS. Or are you talking about something else, like SF Symbols on iOS 13, perhaps?

Indeed, the Navigation router is just what I was looking for.

image

As you will notice the first icon (set through the image prop) appears less crisp than the second icon (set through the systemItem prop).

So, based on your previous feedback, it appears there are three options for us:

1) fix the blurriness in the image prop 2) add more systemItem default icons (SF Symbols) 3) recommend users to use a custom tabbar if they need more than the 12 default icons (which may be the majority of users)

Option 1 seems like the most desirable course of action (correct me if I'm wrong). Option 2 is something we can consider if option 1 is not feasible. Option 3 is also fine, although it would make the library slightly less attractive.

Now let's get Navigation router to become the golden standard in the react ecosystem which is where it deserves to be.

grahammendick commented 2 years ago

Yes, let's fix the blurriness.

If you use that image as the source of a React Native Image component is it also blurry? If you use it as the image of a BarButton in the NavigationBar is it also blurry? If you set a selectedTintColor and unselectedTintColor on the TabBar is the image tinted like the search icon?

Now let's get Navigation router to become the golden standard in the react ecosystem which is where it deserves to be.

I've been trying but it ain't easy. You saw how few upvotes my Native Twitter on the Web reddit post got. I'm swimming against the tide.

grahammendick commented 2 years ago

@10000multiplier Also, can you try the home image from my Twitter example and see if you've still got a blur, please?

vbylen commented 2 years ago

If you use that image as the source of a React Native Image component is it also blurry?

Yes.

If you use it as the image of a BarButton in the NavigationBar is it also blurry?

Yes.

If you set a selectedTintColor and unselectedTintColor on the TabBar is the image tinted like the search icon?

Yes.

If I double the pixel density of the image it looks like this:

image

I've been trying but it ain't easy. You saw how few upvotes my Native Twitter on the Web reddit post got. I'm swimming against the tide.

You are. I sent a PR to change the official React Native docs to include your library.

vbylen commented 2 years ago

@10000multiplier Also, can you try the home image from my Twitter example and see if you've still got a blur, please?

Still getting a blur with that one.

grahammendick commented 2 years ago

Thanks for your PR to update the official docs! You're a ⭐ I tried to get the official docs updated a while back but no dice. I think I went in too strong. Hopefully you'll have better luck.

You said it's blurry when it's the source of a React Native Image component, so I don't think it's a problem with the Navigation router. Could it be a device setting that's causing the blur?

grahammendick commented 2 years ago

Could you run my Twitter native sample and see if the tab images are blurred?

vbylen commented 2 years ago

@grahammendick yes, it may be related to react native's treatment of pixel units vs size units. See this stackoverflow post and React Native docs.

vbylen commented 2 years ago

Using the home.png image from the twitter sample and the pixelratio:


import { PixelRatio, Image } from 'react-native'

const SharpImage = () => {

const pixelRatio = PixelRatio.get()
const height = 24 / pixelRatio
const width = 24 / pixelRatio

return(
    <Image
        source={require('../../home.png')}
        style={{ height, width }}
    />
)
}

indeed fixes the blur.

<TabBarItem /> would have to expose height and width props to do this though.

grahammendick commented 2 years ago

Nice. You can fix that with Static Image Resouces. For example, create a home@2x.png alongside home.png and React Native will pick the right one for the screen density

vbylen commented 2 years ago

Brilliant!

Thank you once again.

grahammendick commented 2 years ago

No problem. And thank you once again for raising that PR to update the React Native docs!