React Native SVG kullanımı

İster mobil olsun ister web uygulaması olsun, ikonlar uygulamaların vazgeçilmez bileşenleridir. Günümüzde birçok uygulamada olduğu gibi React Native uygulamalarında da ikon gereksinimi mevcut. Web’in aksine, React Native’de SVG desteği bulunmuyor. Çünkü native platformların altında yatan Image/UIImage bileşenlerinden dolayı Android’de ve iOS’te doğrudan bir SVG dosyasını işleme yeteneği yok. Bunun yerine Android’de vector drawables, iOS’te is vector PDF dosyaları ile geliştirim yapılıyor. Bu nedenle birçok geliştirici, projesine uygulama ikonlarını PNG olarak dahil ediyor. Halihazırdaki ikon setlerini kullanmak için ise react-native-vector-icons kütüphanesinden faydalanılıyor.

Bugün sizlere react-native-svg kütüphanesini kullanarak nasıl bir svg dosyasını ekrana basabileceğinizi göstereceğim. Öncelikle boş bir RN projesi oluşturalım. Ben typescript template’ini kullanmayı tercih ediyorum. Bu template’i kullanmak için react native CLI’ının, community sürümünde olması gerekiyor. Aksi halde buradaki yönergeleri izleyerek son sürümü yükleyebilirsiniz. Projeyi aşağıdaki komut vasıtasıyla oluşturalım:

npx react-native init ReactNativeSVGSample --template react-native-template-typescript@6.2.0
cd ReactNativeSVGSample

SVG kütüphanesini aşağıdaki gibi yükleyebilirsiniz:

yarn add react-native-svg

ios platformu için pod’ları yüklemeniz gerekiyor:

cd ios && pod install && cd ..

Vscode ile projeyi açmak için aşağıdaki komutu çalıştıralım:

code .

Çalışma zamanında url’deki bir svg dosyasının indirilerek, react-native-svg bileşenlerine dönüştürülme suretiyle ekrana basılmasını aşağıdaki gibi test edebilirsiniz:

import * as React from 'react';
import { SvgUri } from 'react-native-svg';

const App = () => {
return (
<SvgUri
width="100%"
height="100%"
uri="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/android.svg"
/>
);
}
export default App;

Uygulamayı çalıştırdığınızda android ikonunu görebilirsiniz:

Şimdi local svg dosyaları ile çalışma adımına gelelim.

Yerel SVG dosyalarının derleme anında SvgXml bileşenlerine dönüştürülmesi için react-native-svg-transformer kütüphanesini yüklememiz gerekiyor:

yarn add --dev react-native-svg-transformer

Bu kütüphane, çalışma zamanında, svg dosyalarını React bileşenlerine dönüştürecektir. metro-config.js dosyasını aşağıdaki gibi ayarlamamız gerekiyor:

const { getDefaultConfig } = require("metro-config");

module.exports = (async () => {
const {
resolver: { sourceExts, assetExts }
} = await getDefaultConfig();
return {
transformer: {
babelTransformerPath: require.resolve("react-native-svg-transformer")
},
resolver: {
assetExts: assetExts.filter(ext => ext !== "svg"),
sourceExts: [...sourceExts, "svg"]
}
};
})();

Eğer typescript kullanıyorsanız declarations.d.ts dosyasını da root dizininde oluşturmanız gerekiyor:

declare module "*.svg" {
import { SvgProps } from "react-native-svg";
const content: React.FC<SvgProps>;
export default content;
}

Artık App.js içerisinde aşağıdaki gibi bir SVG dosyasını import edip kullanabilirsiniz:

import * as React from 'react';
import AndroidIcon from './android.svg';
const App = () => {
return (
<AndroidIcon width="100%" height="100%" />
);
}
export default App;

Uygulamanın çalışma zamanında svg dosyasını yorumlamasını istiyorsanız, babel-plugin-inline-import kütüphanesini eklemeniz gereklidir:

npm install babel-plugin-inline-import --save-dev

Bu plugin’in kullanımı için .babelrc dosyasını aşağıdaki gibi oluşturalım:

{
"presets": ["module:metro-react-native-babel-preset"],
"plugins": [
[
"babel-plugin-inline-import",
{
"extensions": [".svg"]
}
]
]
}

Runtime’da dönüşün yapılması için App.js dosyası aşağıdaki gibi olmalıdır:

import * as React from 'react';
import { SvgXml } from 'react-native-svg';
import AndroidIcon from './android.svg';
const App = () => {
return (
<SvgXml width="100%" height="100%" xml={AndroidIcon} />
);
}
export default App;

İkon rengini değiştirme işlemi, SVG dosyalarındaki fill özelliğinin elle silindiğinde ve ilgili ikon bileşenine fill parametresi eklendiğinde sağlanıyor. Örneğin aşağıdaki gibi <path> elemanından fill özelliği çıkarılmış bir youtube.svg dosyası olsun:

<?xml version="1.0" ?>
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M21.582,6.186c-0.23,-0.86 -0.908,-1.538 -1.768,-1.768C18.254,4 12,4 12,4S5.746,4 4.186,4.418c-0.86,0.23 -1.538,0.908 -1.768,1.768C2,7.746 2,12 2,12s0,4.254 0.418,5.814c0.23,0.86 0.908,1.538 1.768,1.768C5.746,20 12,20 12,20s6.254,0 7.814,-0.418c0.861,-0.23 1.538,-0.908 1.768,-1.768C22,16.254 22,12 22,12S22,7.746 21.582,6.186zM10,15.464V8.536L16,12L10,15.464z"/>
</svg>

Renk değerini aşağıdaki gibi App.js içerisinde verebiliriz:

import * as React from 'react';
import { SvgXml } from 'react-native-svg';
import YoutubeIcon from './youtube.svg';
const App = () => {
return (
<SvgXml width="100%" height="100%" xml={YoutubeIcon} fill="#dd0000"/>
);
}
export default App;

Ekran görüntüsü aşağıdaki gibi olacaktır:

SVGR, temel olarak svg dosyalarının içeriğini React bileşenleri haline getiren bir CLI aracıdır. Daha sonra oluşan React bileşenlerini uygulamanızda kullanabilirsiniz. Eğer denemek istiyorsanız svgr aracını yükledikten sonra buradaki gist’ten faydalanabilirsiniz.

React Native’de direkt olarak SVG desteği olmasa da, farklı kütüphanelerin yardımıyla bu özelliği kullanmak mümkün hale geliyor. Uygulama ikonlarını ayrı ayrı PNG dosyalarını oluşturmak yerine üstte anlattığım gibi SVG olarak kullanmanız daha efektif olacaktır.

Bu yazı hakkında soru ve görüşleriniz varsa alttaki yorum kısmından yazabilirsiniz. Ayrıca yazılarımın devamının gelmesinde teşvik/destek olmak istiyorsanız, soldaki alkış butonuna dilediğiniz kadar basabilirsiniz. Teşekkürler 🤗

Sonraki yazımda görüşmek üzere. Hoşçakalın…

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store