サイトロゴ

Enjoy Creating
Web & Mobile Apps

MENU BOX
WEB
MOBILE
OPEN

ホーム

 > 

 > 

【React Native】モバイルアプリの画面をスクロールできるようにする【ScrollView】

【React Native】モバイルアプリの画面をスクロールできるようにする【ScrollView】

この記事にはプロモーションが含まれています。

HTML/CSSを用いたWebページ制作であれば、要素(コンテンツ)が画面の幅に収まらない場合は自動的にブラウザにスクロールバーが表示され、画面をスクロールできるようにしてくれます。

しかし、モバイルアプリではコンテンツの幅に応じて自動的にスクロールできるように調整してくれるような仕組みはありません。

React Nativeの最も基本的なコンポーネントであるViewは、HTMLのdiv要素のような役割を果たしますが、div要素と違ってコンテンツが画面に収まらない場合でもスクロールバーは表示されないようになっています。

なのでモバイルアプリ開発においては、画面をスクロールできるようにしておきたい場合、スクロールできる専用のパーツで組み立てる必要があります。

そこで今回は、スクロールを可能にするコンポーネントであるScrollViewの基本的な使い方と、便利なプロパティ・メソッドをご紹介します!

この記事を読むことで分かること
  • ・Viewでコンテンツが画面内に収まらないとどうなるか
  • ・ScrollViewの基本的な使い方
  • ・ScrollViewで使える便利なプロパティ、メソッド

– 目次 –

Viewではどうなるか?

ScrollViewを紹介する前に、まずは『画面内にコンテンツが収まらないものをViewコンポーネントを使って表すとどうなるのか?』を確認しておきましょう。

下のサンプルコードは、文字サイズを大きめにして長文(ダミーテキスト)を配置し、おそらくどんなサイズのスマホでも画面内に収まらないように調整したものです。

App.js

import React from 'react';
import {
    SafeAreaView,
    StyleSheet,
    Text,
    View,
} from 'react-native';

function App() {
    return (
        <SafeAreaView>
            <View style={styles.scrollView}>
            <Text style={styles.text}>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
            eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
            minim veniam, quis nostrud exercitation ullamco laboris nisi ut
            aliquip ex ea commodo consequat. Duis aute irure dolor in
            reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
            pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
            culpa qui officia deserunt mollit anim id est laborum.
            </Text>
            </View>
        </SafeAreaView>
    );
};

const styles = StyleSheet.create({
    scrollView: {
        backgroundColor: 'pink',
        marginHorizontal: 20,
    },
    text: {
        fontSize: 42,
    }
});

export default App;

そして、このコードの表示結果は下の画像のようになります。

表示結果

コンテンツがViewコンポーネントに収まりきらず、スクロールできない様子

静止画なので分かりづらいかもしれませんが、コンテンツが画面内に収まっていない(テキストが見切れている)のに画面をスクロールできない状態になってしまっています。

この時、Webページ制作の経験が豊富でCSSに詳しい人ほど、『overflow-yをscrollにすれば良いのでは?』と考えてしまうかもしれませんが、それでは解決できません。

StyleSheet APIのおかげで、CSSっぽく見た目を調整できるようになっているものの、Webブラウザで表示されるわけではない=CSSが機能しているわけではないからです。

React NativeではJavaScriptでコードが書けるとは言え、やはりWebページ制作とモバイルアプリ制作では異なる部分が多々あります。

郷に入っては郷に従えと言うように、モバイルアプリ制作ではWebページ制作の感覚を一旦端っこに置いておき、Webページとは異なるものを作っていることを認識しておかないと、混乱の元となるので気をつけましょう。

というわけで、スクロールさせたい画面=ViewコンポーネントではNGというポイントをまず押さえておくことが大切です。

    POINT!
  1. ・Viewコンポーネントではコンテンツが画面に収まらない場合でもスクロールバーが表示されず、スクロールできない!
  2. ・CSSで調整できるわけではないので、CSSのoverflowプロパティを適用させようとしてもダメ!
  3. ・React NativeではJavaScriptでコードが書けるが、Webページ作成とは根本的に異なることを認識しておこう!

ScrollViewでスクロールできるようにする

Viewコンポーネントでは画面をスクロールできないことがわかりましたね。では、スクロールできるようにするにはどうすれば良いのでしょうか?

答えはとても簡単で、Viewコンポーネントの代わりにScrollViewコンポーネントでラップすればそれだけでOKです。

ScrollViewには様々なpropsを指定することができますが、単にスクロールできる画面にしたいだけであればpropsの指定も特に必要ありません。

前章で示したサンプルコードのViewコンポーネントを、ScrollViewコンポーネントに置き換えたものが下のコードです。

App.js

import React from 'react';
import {
    SafeAreaView,
    StyleSheet,
    Text,
    ScrollView,
} from 'react-native';

function App() {
    return (
        <SafeAreaView>
            <ScrollView style={styles.scrollView}>
                <Text style={styles.text}>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
                eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
                minim veniam, quis nostrud exercitation ullamco laboris nisi ut
                aliquip ex ea commodo consequat. Duis aute irure dolor in
                reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
                pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
                culpa qui officia deserunt mollit anim id est laborum.
                </Text>
            </ScrollView>
        </SafeAreaView>
    );
};

const styles = StyleSheet.create({
    scrollView: {
        backgroundColor: 'pink',
        marginHorizontal: 20,
    },
    text: {
        fontSize: 42,
    }
});

export default App;

そしてこのコードの表示結果が下の動画です。

表示結果

画面がスクロールできるようになっていることが確認できました!

ところで、この時点でこんな疑問が湧いてこないでしょうか?

『コンテンツが画面に収まらなくてもスクロールできることが保証されるなら、ScrollViewだけを使えば良いのでは?(=Viewを使う必要はないのでは?)』

スクロールに対応していないdiv要素(View)と、対応しているdiv要素(ScrollView)があるというふうに考えたら、スクロールに対応しているdiv要素=ScrollViewを使っておけば間違いなさそうな気がします。

しかし、ScrollViewは決して万能ではなく、一つ大きな問題を抱えています。

それは、『スクロールが必要ない場合でも、スクロールできる挙動を見せる』ことです。

例えば、アプリのタイトルテキストのみを表示させる画面で考えてみましょう。

この場合、当然画面をスクロールできるようにしておく必要はないですし、画面に指が触れても(スクロールさせようとしても)画面がガクガク動かないようにしておきたいですよね。

このようなケースでScrollViewを使うと、スクロールできなくて良いのにスクロールできるような挙動を見せてしまいます。(詳しくは下の動画をご覧ください)

スクロールできるような挙動を見せる

上の動画のように、スクロールの必要がないのにスクロールできそうな挙動を見せてしまうと、ユーザーが混乱したり誤解したりする原因になります。

なので、状況に応じてViewとScrollViewをしっかり使い分けることが重要です。

    POINT!
  1. ・画面をスクロールできるようにしたいだけなら、ScrollViewでラップするだけでOK!
  2. ・ScrollViewは、スクロールの必要がない場面でもスクロールできそうな挙動を見せてしまう!
  3. ・状況に応じて、スクロールできないViewとスクロールできるScrollViewを使い分けよう!

ScrollViewで使える便利なプロパティ、メソッド

ただ画面をスクロールできるようにしたいだけであれば、すでに説明したようにpropsの指定は特に必要ないのですが、ScrollViewには便利なプロパティやメソッドがたくさん用意されています。

今回はその中でも割と使用頻度が高いと思われるものや、簡単に扱えるものをご紹介します。


スクロールされるとキーボードが隠れるようにする

皆さんは、スマホアプリのお問い合わせフォームやアカウント作成の画面で、次のような経験をしたことはないでしょうか?

『フォームの入力が終わり、次の入力に進もうとして画面スクロールさせても、キーボードが引っ込んでくれなくて画面が見づらい

キーボードを非表示にするためにどこをタップしたらいいのかも分かりづらく、イラッとしたことがあることがあるのは、きっと筆者だけではないと思います。笑

今ひとつイメージが湧かないという方は、下の動画をご覧ください。画面をスクロールさせてもキーボードが引っ込まないと邪魔になるというのが、なんとなく分かるかと思います。

表示結果

これを解決してくれる便利なpropsが、keyboardDismissModeです。

このpropsの値をon-dragに指定すると、スクロールされた時にキーボードが表示状態になっていた場合は非表示にしてくれます。

keyboardDismissModeに指定できる値は、none/on-drag/interactive(iOSのみ)だけであるため取り扱いも簡単で、初心者でもすぐにでもアプリ開発に活用できます。

下はScrollViewにkeyboardDismissMode propを指定したサンプルコードです。

App.js

import React from 'react';
import {
    SafeAreaView,
    StyleSheet,
    Text,
    ScrollView,
    TextInput,
} from 'react-native';

function App() {
    return (
        <SafeAreaView>
            <ScrollView style={styles.scrollView} keyboardDismissMode='on-drag'>
                <TextInput style={styles.input} />
                <Text style={styles.text}>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
                eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
                minim veniam, quis nostrud exercitation ullamco laboris nisi ut
                aliquip ex ea commodo consequat. Duis aute irure dolor in
                reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
                pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
                culpa qui officia deserunt mollit anim id est laborum.
                </Text>
            </ScrollView>
        </SafeAreaView>
    );
};

const styles = StyleSheet.create({
    scrollView: {
        backgroundColor: 'pink',
        marginHorizontal: 20,
    },
    text: {
        fontSize: 42,
    },
    input: {
        height: 40,
        margin: 12,
        borderWidth: 1,
        padding: 10,
    }
});

export default App;

表示結果

スクロールさせると同時にキーボードが隠れてくれるので、画面がとても見やすくなりましたね!

キーボードを非表示にするためにどこか特定の場所をタップする必要もなくなるので、ユーザー体験も向上できます。


一番下までスクロールさせる

お次は、『ScrollViewの下まで自動でスクロールさせる機能』を簡単に実装する方法をご紹介します。
モバイルアプリに限らず、Webページでもよく見かけますね。

React NativeのScrollViewコンポーネントには、scrollToEnd()というメソッドが用意されており、これを使用することでScrollViewの一番下まで自動的にスクロールさせることができます。

先ほど紹介した、keyboardDismissModeはprop(プロパティ)でしたが、こちらはメソッドであるため少し使い方が異なる点に注意が必要です。

具体的には、useRefを使ってScrollViewを参照できる状態にしておき、その上でscrollToEnd()メソッドを呼び出せばOKです。

下のサンプルコードは、ButtonコンポーネントからscrollToEnd()メソッドを呼び出し、ボタンをタップすると下まで自動でスクロールできるようにしたものです。

App.js

import React, { useRef } from 'react';
import {
    SafeAreaView,
    StyleSheet,
    Text,
    ScrollView,
    Button,
} from 'react-native';

function App() {

    const scrollViewRef = useRef();

    function handleScrollToEnd() {
        scrollViewRef.current.scrollToEnd();
    }

    return (
        <SafeAreaView>
            <ScrollView style={styles.scrollView} ref={scrollViewRef}>
                <Button 
                title="To Bottom"
                onPress={handleScrollToEnd}
                />
                <Text style={styles.text}>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
                eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
                minim veniam, quis nostrud exercitation ullamco laboris nisi ut
                aliquip ex ea commodo consequat. Duis aute irure dolor in
                reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
                pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
                culpa qui officia deserunt mollit anim id est laborum.
                </Text>
            </ScrollView>
        </SafeAreaView>
    );
};

const styles = StyleSheet.create({
    scrollView: {
        backgroundColor: 'pink',
        marginHorizontal: 20,
    },
    text: {
        fontSize: 42,
    }
});

export default App;

表示結果

動画ではボタンをタップしたタイミングが分かりづらいかもしれませんが、ボタンタップで自動的にScrollViewの下までスクロールさせることができています!

使いどころとしては、全文を読んでもらう必要のない、重要性の低いお知らせページをスキップできるようにしたい場合などに役立つかなと思います。

他にも色々と便利なプロパティやメソッドがあるので、気になる方はReact Nativeの公式ページで確認してみてください。

なお、ScrollViewのpropsはAndroidのみ若しくはiOSのみというものが多いので、使用する際は公式の説明をよく読んで理解してから使用することをおすすめします。(今回紹介したものはAndroid・iOSどちらでも使えます)

    POINT!
  1. ・keyboardDismissModeプロパティをon-dragにすることで、スクロールと同時にキーボードを非表示にできる!
  2. ・scrollToEnd()メソッドを利用することで、ScrollViewの一番下まで自動でスクロールさせられる!
  3. ・ScrollViewのpropsは片方のOSにしか対応していないものも多いので、使用する際は気をつけよう!

« »

カテゴリーリンク

著者について- author profile -

ROYDOプロフィール写真
Michihiro

モバイルアプリ(iOS・Android)ディベロッパー&デザイナー

これまでに、可読性の高いカラーパターンを自動で生成するアプリや、『第3火曜日』といった形式で通知をスケジュールできるアプリなどを制作。

サブでWebデザイン・フロントエンドエンジニアとしても活動しています。

📝ツール・言語:JavaScript/React Native/Kotlin/Android Studio/Swift/SwiftUI

🎓資格:基本情報技術者/ウェブデザイン技能検定3級

Twitterアイコン Instagramアイコン