[SwiftUI] インスタっぽいレイアウトを作ってみた
SwiftUIでインスタっぽいレイアウトを組んでみました😄
ホーム画面だけですが・・
viewの構成はこんな感じです!
StoryRow
ストーリーズの部分のViewです😄
横スクロールでアイコンとアカウント名を表示します!
struct StoryRow: View {
var stories: [Story]
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .top, spacing: 0) {
ForEach(self.stories) { story in
VStack(alignment: .center) {
AccountIcon(image: story.image, size: 90)
Text(story.name)
.frame(width: 100)
.font(.caption)
}
.padding(.leading, 10)
.padding(.top, 15)
}
}
}
}
}
アカウントのアイコンはいろんなところで使うので、レイアウトをAccountIconというクラスにして、共通で使えるようにしています。
AccountIcon.swift
struct AccountIcon: View {
let image: Image
let size: CGFloat
var body: some View {
image
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: size, height: size, alignment: .center)
.clipShape(Circle())
}
}
PostRow
タイムラインの部分のビューです😄
投稿の情報を縦スクロールで表示します。
struct PostRow: View {
var posts: [Post]
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
ForEach(self.posts) { post in
VStack(alignment: .leading) {
// アカウント情報
HStack {
AccountIcon(image: post.image, size: 30)
Text(post.name)
.font(.caption)
.fontWeight(.bold)
.frame(width: 100, alignment: .leading)
Spacer()
Image(systemName: "ellipsis")
}
.padding(.horizontal, 12.0)
.padding(.vertical, 5.0)
// 投稿画像
post.image.resizable()
.scaledToFill()
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.width)
.clipped()
// いいねとかのアイコン
HStack {
Group {
Image(systemName: "heart")
Image(systemName: "message")
Image(systemName: "paperplane")
}
.padding(.trailing, 5.0)
Spacer()
Group {
Image(systemName: "bookmark")
}
}
.padding(.horizontal, 12.0)
.padding(.vertical, 5.0)
// いいね!のところ
HStack(spacing: 0) {
Text("いいね!:").font(.caption)
ForEach(0 ..< post.likes.count) {
Text(post.likes[$0]).font(.caption).fontWeight(.bold)
if post.likes[$0] != post.likes.last {
Text("、").font(.caption)
}
}
}
.padding(.horizontal, 12.0)
.padding(.vertical, 1.0)
// 投稿テキスト
HStack(spacing: 0) {
Text(post.name)
.font(.caption)
.fontWeight(.bold)
.padding(.trailing, 5.0)
Text(post.contentText).font(.caption)
}
.padding(.horizontal, 12.0)
.padding(.bottom, 5.0)
Group {
Text("3分前").font(.caption).foregroundColor(Color.gray)
}
.padding(.horizontal, 12.0)
.padding(.bottom, 10.0)
}
}
}
}
}
HomeView
ホーム画面のビューです😄
struct HomeView: View {
var body: some View {
VStack {
StoryRow(stories: dataStore.stories)
Divider()
PostRow(posts: dataStore.posts)
}
}
}
上記で作ったStoryRowとPostRowを追加しています。
間にあるDividerは線を表示するビューです。
ContentView
ContentViewが今回一番親になるViewです😊
struct ContentView: View {
var body: some View {
NavigationView {
TabView {
HomeView().tabItem { Image(systemName: "house") }
Text("検索画面").tabItem { Image(systemName: "magnifyingglass") }
Text("投稿する").tabItem { Image(systemName: "plus.app") }
Text("いいねの情報").tabItem { Image(systemName: "heart") }
Text("アカウント情報").tabItem { Image(systemName: "person.crop.circle.fill") }
}
.accentColor(.black)
.navigationBarTitle("Otastagram", displayMode: .inline)
.navigationBarItems(leading: Image(systemName: "camera"), trailing: Image(systemName: "paperplane"))
}
}
}
NavigationViewとTabViewを追加します。
今回はホーム画面だけ作ったので、TabItemにHomeViewを指定し、それ以外はとりあえずアイコンだけ表示しました。
完成
ストーリーズとタイムラインの部分をスクロールできます🎉
おまけ
アイコンは全てSF Symbolを使っています。
インストールして起動すると、こんな画面が表示されます。
あとは使いたいアイコンを検索して、アイコン名をコピーしてImageViewのsystemNameに指定します🙂
Image(systemName: "heart")
とても簡単にバリエーション豊かなアイコンたちを使うことができます🎉
この記事が気に入ったらサポートをしてみませんか?