TigerCow.Door

'리액트 네이티브 어플 만들기'에 해당되는 글 1건


지난글

리액트 네이티브 #4_ 인스타그램(Instagram) UI 무작정 따라하기 (1)

리액트 네이티브 #5_ 인스타그램(Instagram) UI 무작정 따라하기 (2)


Github

https://github.com/doorBW/INSTA-by-react-native



안녕하세요. 문범우입니다. 

지난 포스팅에서는 Home 화면에 피드를 추가하는 과정까지 진행해보았습니다.


이번 포스팅에서는 Home 화면에서 상단에 있는 스토리바를 추가해보도록 하겠습니다.

해당 포스트를 통해서 나오는 결과물은 아래와 같습니다.



1. 스토리바 만들기


우리는 스토리바를 추가하기 위해 HomeTab.js 에서 작업을 진행합니다.

이전 포스팅을 통해 현재 HomeTab.js의 코드는 아래와 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet
    } from 'react-native';
import { Icon, Container, Content } from 'native-base';
 
import CardComponent from '../CardComponent';
 
class HomeTab extends Component{
 
    static navigationOptions = {
        tabBarIcon: ({ tintColor }) => (
            < Icon name='ios-home' style={{color:tintColor}} />
        )
    }
 
    render(){
        return (
            <Container style = {style.container}>
                <Content>
                    <CardComponent imageSource='1' likes='2324'/>
                    <CardComponent imageSource='2' likes='46'/>
                    <CardComponent imageSource='3' likes='208'/>
                </Content>
            </Container>
        );
    }
}
export default HomeTab;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white'
    }
})
cs


이제 스토리바를 추가해 볼건데, 먼저 스토리바의 위치와 형태를 잡아보도록 하겠습니다.

스토리바는 Content 태그 안에 위치하며 CardComponent보다 위에 존재합니다.

따라서 위의 코드에서 22번줄과 23번줄 사이에 코드를 작성하는 것으로 시작합니다.

<View> 태그로 기준을 잡고, '스토리' 와 '모두 보기' 텍스트를 아래와 같이 넣어줍니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet
    } from 'react-native';
import { Icon, Container, Content } from 'native-base';
 
import CardComponent from '../CardComponent';
 
class HomeTab extends Component{
 
    static navigationOptions = {
        tabBarIcon: ({ tintColor }) => (
            < Icon name='ios-home' style={{color:tintColor}} />
        )
    }
 
    render(){
        return (
            <Container style = {style.container}>
                <Content>
                    <View>
                        <Text>스토리</Text>
                        <Text>모두 보기</Text>
                    </View>
                    <CardComponent imageSource='1' likes='2324'/>
                    <CardComponent imageSource='2' likes='46'/>
                    <CardComponent imageSource='3' likes='208'/>
                </Content>
            </Container>
        );
    }
}
export default HomeTab;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white'
    }
})
cs


위의 코드를 보시면 23번줄 ~ 26번줄에 View태그로 감싸져 있는 것을 볼 수 있고 내부에 Text태그로 '스토리'와 '모두 보기' 두개가 입력된 것을 볼 수 있습니다.


조금 더 구조를 세분화해보도록 하겠습니다.



위와 같이 검은색 테두리로 된 스토리바를 현재 추가하려고 하는데, 이는 또 두개의 View로 나눌 수 있습니다.

현재 두개의 텍스트를 넣어준 파란색 테두리와, 스토리를 올린 사람들의 사진이 보일 빨간색 테두리로 나눌 수 있습니다.

따라서, 우리가 위에서 작성한 두개의 텍스트 태그를 또 다른 View 태그로 묶어주고, 그 아래에 다른 View 태그를 만들어줍니다.

그리고 스토리바 전체를 묶고 있는, 검은색 테두리의 View 태그는 높이를 100으로 지정해주며, 파란색 테두리의 View 태그에 필요한 속성도 설정해줍니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet
    } from 'react-native';
import { Icon, Container, Content } from 'native-base';
 
import CardComponent from '../CardComponent';
 
class HomeTab extends Component{
 
    static navigationOptions = {
        tabBarIcon: ({ tintColor }) => (
            < Icon name='ios-home' style={{color:tintColor}} />
        )
    }
 
    render(){
        return (
            <Container style = {style.container}>
                <Content>
                    <View style={{height:100}}>
                        <View style={{flex:1, flexDirection:'row', justifyContent:'space-between', alignItems:'center', paddingHorizontal:7}}>
                            <Text>스토리</Text>
                            <Text>모두 보기</Text>
                        </View>
                        <View>
 
                        </View>
                    </View>
                    <CardComponent imageSource='1' likes='2324'/>
                    <CardComponent imageSource='2' likes='46'/>
                    <CardComponent imageSource='3' likes='208'/>
                </Content>
            </Container>
        );
    }
}
export default HomeTab;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white'
    }
})
cs


24번줄의 View 태그가 파란색 테두리로써 '스토리' 와 '모두 보기' 텍스트를 감싸고 있습니다. 이들의 flex는 1로 지정해주고, 가로로 정렬되게 하며 space-between 속성으로 서로 양쪽끝에 오도록 합니다.


이제 빨간색 테두리의 형태를 잡아보도록 하겠습니다.

빨간색 테두리 View는 파란색 테두리보다 커야합니다.

따라서 flex는 3으로 지정합니다. 또한 빨간색 테두리 내부에 들어가는 스토리의 사진들은 가로로 스크롤할 수 있기 때문에, 이를 위해 ScrollView 를 import에 추가해주어야 합니다. 그리고 ScrollView 내부에는 Thumbnail 을 통해 여러개의 이미지를 넣어줍니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet,
    ScrollView
    } from 'react-native';
import { Icon, Container, Content, Thumbnail } from 'native-base';
 
import CardComponent from '../CardComponent';
 
class HomeTab extends Component{
 
    static navigationOptions = {
        tabBarIcon: ({ tintColor }) => (
            < Icon name='ios-home' style={{color:tintColor}} />
        )
    }
 
    render(){
        return (
            <Container style = {style.container}>
                <Content>
                    <View style={{height:100}}>
                        <View style={{flex:1, flexDirection:'row', justifyContent:'space-between', alignItems:'center', paddingHorizontal:7}}>
                            <Text>스토리</Text>
                            <Text>모두 보기</Text>
                        </View>
                        <View style={{flex:3}}>
                            <ScrollView>
                                <Thumbnail source={require('../../assets/beomwoo.jpeg')}/>
                                <Thumbnail source={require('../../assets/1.jpg')}/>
                                <Thumbnail source={require('../../assets/2.jpg')}/>
                                <Thumbnail source={require('../../assets/3.jpg')}/>
                                <Thumbnail source={require('../../assets/4.jpg')}/>
                                <Thumbnail source={require('../../assets/5.jpg')}/>
                                <Thumbnail source={require('../../assets/6.jpeg')}/>
                                <Thumbnail source={require('../../assets/7.jpg')}/>
                            </ScrollView>
                        </View>
                    </View>
                    <CardComponent imageSource='1' likes='2324'/>
                    <CardComponent imageSource='2' likes='46'/>
                    <CardComponent imageSource='3' likes='208'/>
                </Content>
            </Container>
        );
    }
}
export default HomeTab;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white'
    }
})
cs


29번줄을 보시면 빨간색 테두리 View의 flex를 3으로 설정해준것을 확인할 수 있습니다.

그리고 그 다음에 ScrollView를 사용하기 위해 6번줄과 같이 ScrollView를 import에 추가해주었으며 ScrollView에 여러개의 Thumbnail을 통해 사진을 넣어 주었습니다.

이렇게 하고 시뮬레이터를 확인해보면, 스토리바 위치에 사진들이 여러개 있지만, 사진들이 세로로 정렬되어 있어 이상한 것을 확인할 수 있습니다.

각각의 썸네일의 스타일도 수정해보고, 스토리바의 속성도 설정해보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet,
    ScrollView
    } from 'react-native';
import { Icon, Container, Content, Thumbnail } from 'native-base';
 
import CardComponent from '../CardComponent';
 
class HomeTab extends Component{
 
    static navigationOptions = {
        tabBarIcon: ({ tintColor }) => (
            < Icon name='ios-home' style={{color:tintColor}} />
        )
    }
 
    render(){
        return (
            <Container style = {style.container}>
                <Content>
                    <View style={{height:100}}>
                        <View style={{flex:1, flexDirection:'row', justifyContent:'space-between', alignItems:'center', paddingHorizontal:7}}>
                            <Text>스토리</Text>
                            <Text>모두 보기</Text>
                        </View>
                        <View style={{flex:3}}>
                            <ScrollView 
                                horizontal={true}
                                showsHorizontalScrollIndicator={false}
                                contentContainerStyle={{
                                    alignItems:'center',
                                    paddingStart:5,
                                    paddingEnd:5
                                }}
                            >
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/beomwoo.jpeg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/1.jpg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/2.jpg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/3.jpg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/4.jpg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/5.jpg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/6.jpeg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/7.jpg')}/>
                                
                            </ScrollView>
                        </View>
                    </View>
                    <CardComponent imageSource='1' likes='2324'/>
                    <CardComponent imageSource='2' likes='46'/>
                    <CardComponent imageSource='3' likes='208'/>
                </Content>
            </Container>
        );
    }
}
export default HomeTab;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white'
    }
})
cs


먼저, 30번줄 ~ 38번줄을 보시면 ScrollView에서 몇가지 속성을 설정한 것을 확인할 수 있습니다. 내부의 Thumbnail들이 가로로 정렬하도록 horizontal 을 true로 설정하였고, 스크롤 바가 보이지 않도록 설정하였으며 내부 아이템들의 스타일또한 설정하였습니다.

그리고 각각의 Thumbnail에 모두 동일하게, margin 값을 5로 설정하며 사진의 테두리에 빨간색 선이 있도록 설정해주었습니다.


이렇게까지 하면 어느정도 자리잡은 스토리바의 형태가 보입니다.

마무리로 약간의 수정을 해보도록 하겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import React, { Component } from 'react';
import { 
    View,
    Text,
    StyleSheet,
    ScrollView
    } from 'react-native';
import { Icon, Container, Content, Thumbnail } from 'native-base';
 
import CardComponent from '../CardComponent';
 
class HomeTab extends Component{
 
    static navigationOptions = {
        tabBarIcon: ({ tintColor }) => (
            < Icon name='ios-home' style={{color:tintColor}} />
        )
    }
 
    render(){
        return (
            <Container style = {style.container}>
                <Content>
                    <View style={{height:100}}>
                        <View style={{flex:1, flexDirection:'row', justifyContent:'space-between', alignItems:'center', paddingHorizontal:7}}>
                            <Text style={{fontWeight:'bold'}}>스토리</Text>
                            <View style={{flexDirection:'row', alignItems:'center'}}>
                                <Icon name='md-play' style={{fontSize:14}}/>
                                <Text style={{fontWeight:'bold'}}>모두 보기</Text>
                            </View>
                        </View>
                        <View style={{flex:3}}>
                            <ScrollView 
                                horizontal={true}
                                showsHorizontalScrollIndicator={false}
                                contentContainerStyle={{
                                    alignItems:'center',
                                    paddingStart:5,
                                    paddingEnd:5
                                }}
                            >
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/beomwoo.jpeg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/1.jpg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/2.jpg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/3.jpg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/4.jpg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/5.jpg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/6.jpeg')}/>
                                <Thumbnail style={{marginHorizontal:5, borderColor:'red', borderWidth:2}} source={require('../../assets/7.jpg')}/>
                                
                            </ScrollView>
                        </View>
                    </View>
                    <CardComponent imageSource='1' likes='2324'/>
                    <CardComponent imageSource='2' likes='46'/>
                    <CardComponent imageSource='3' likes='208'/>
                </Content>
            </Container>
        );
    }
}
export default HomeTab;
 
const style = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white'
    }
})
cs


수정된 것은 26번줄 ~ 30번줄 입니다.

먼저, 27번줄 ~ 30번줄을 보시면 하나의 View태그가 추가되어 아까 있던 '모두 보기' 텍스트와 새롭게 Icon 텍스트를 감싸고 있는 것을 볼 수 있습니다.

인스타그램의 모두보기 옆에 아이콘이 있기 때문에 이를 추가해주었고 해당 아이콘과 '모두보기'텍스트를 하나의 View태그로 묶어주면서, 가로정렬 등의 스타일을 수정하였습니다.

또한 각각의 텍스트가 두껍게 보이도록 bold 속성을 추가해주었습니다.


이렇게 하여 만들어진 스토리바를 확인해보면 다음과 같습니다.



블로그 이미지

Tigercow.Door

Web Programming / Back-end / Database / AI / Algorithm / DeepLearning / etc