위 글은 유튜브 정대리님의 SwiftUI fundamental Tutorial 강좌를 보고 작성한 정리글로
자세한 내용은 유튜브를 통해 확인하시길 권장합니다.
SwiftUI의 List는 UIKit에서 사용한 TableView, CollectionView와 같다고 보면 됨
import SwiftUI
struct MyList: View{
var body: some View{
List{
Text("MY LIST")
}
}
}
List를 쓰면 목차 형식으로 나타남
List 안에 요소를 여러개 넣으면
import SwiftUI
struct MyList: View{
var body: some View{
List{
Text("MY LIST")
Text("MY LIST")
Text("MY LIST")
Text("MY LIST")
Text("MY LIST")
Text("MY LIST")
}
}
}
반복문(ForEach)을 사용하여 List를 처리하기
(ForEach 사용시 반드시 id를 부여해야 함)
첫번째 방법
import SwiftUI
struct MyList: View{
var body: some View{
List{
ForEach(1...10, id: \.self){
Text("MY LIST \($0)")
}
}
}
}
두번째 방법
import SwiftUI
struct MyList: View{
var body: some View{
List{
ForEach(1...10, id: \.self){
itemIndex in Text("MY LIST \(itemIndex)")
}
}
}
}
itemIndex 변수를 만들어서 Text에 넣기
앞 전 Layout 시간에서 만든 커스텀 카드를 List에 넣어 보기
import SwiftUI
struct MyList: View{
var body: some View{
List{
ForEach(1...10, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.green)
}
}
}
}
import SwiftUI
struct MyList: View{
var body: some View{
List{
Section(header: Text("TODAY")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.green)
}
}
Section(header: Text("TOMORROW")){
ForEach(1...3, id: \.self){
itemIndex in
MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.blue)
}
}
}
}
}
List안에 Section을 만들어서 구분할 수 있음
Section 사용 구조
List{
Section(header: Text("Section 명")){
리스트 내용...
}
}
List 자체에 속성 부여 가능
import SwiftUI
struct MyList: View{
var body: some View{
List{
Section(header: Text("TODAY")){
ForEach(1...3, id: \.self){
itemIndex in //Text("MY LIST \(itemIndex)")
MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)", start: "13:00", end: "15:00", bgColor: Color.green)
}
}
Section(header: Text("TOMORROW")){
ForEach(1...3, id: \.self){
itemIndex in //Text("MY LIST \(itemIndex)")
MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)", start: "13:00", end: "15:00", bgColor: Color.blue)
}
}
}
.listStyle(GroupedListStyle())
}
}
import SwiftUI
struct MyList: View{
var body: some View{
List{
Section(header: Text("TODAY")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.green)
}
}
Section(header: Text("TOMORROW")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.blue)
}
}
}
.listStyle(PlainListStyle()) //default listStyle
}
}
listRowInsets(EdgeInsets.init()): List 요소들 간의 간격 조절 가능
import SwiftUI
struct MyList: View{
var body: some View{
List{
Section(header: Text("TODAY")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.green)
}
}
.listRowInsets(EdgeInsets.init())
Section(header: Text("TOMORROW")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.blue)
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 30, bottom: 10, trailing: 10))
}
.listStyle(GroupedListStyle())
}
}
init()값이 비워져 있으면 간격이 0으로 붙어져서 나옴
import SwiftUI
struct MyList: View{
var body: some View{
List{
Section(header: Text("TODAY")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.green)
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 10, bottom: 10, trailing: 10))
Section(header: Text("TOMORROW")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.blue)
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 30, bottom: 10, trailing: 10))
}
.listStyle(GroupedListStyle())
}
}
List 목록 선 지우기
import SwiftUI
struct MyList: View{
init(){
if #available(iOS 14.0, *){
}else{
UITableView.appearance().tableFooterView = UIView()
}
UITableView.appearance().separatorStyle = .none
}
var body: some View{
List{
Section(header: Text("TODAY")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.green)
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 10, bottom: 10, trailing: 10))
Section(header: Text("TOMORROW")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.blue).hideRowSeparator(insets: EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10))
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 30, bottom: 10, trailing: 10))
}
.listStyle(GroupedListStyle())
}
}
코드 그대로 쳤는데 강의 이후로 이루어진 업데이트 때문인지 이렇게 해서는 List 목록 선이 안 없어짐
댓글에 다른 구독자 분이 남겨주신 List 목록 선 지우는 방법
import SwiftUI
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color){
self.insets = insets
var alpha: CGFloat = 0
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "")
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(
minWidth: 0, maxWidth: .infinity, minHeight: Self.defaultListRowHeight, alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(background)
}
}
extension EdgeInsets{
static let defaultListRowInsets = Self(top: 10, leading: 10, bottom: 10, trailing: 10)
}
extension View {
func hideRowSeparator(insets: EdgeInsets = .defaultListRowInsets, background: Color = .white)
-> some View {
modifier(HideRowSeparatorModifier(insets: insets, background: background))
}
}
struct MyList: View{
List{
Section(header: Text("TODAY")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.green)
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 10, bottom: 10, trailing: 10))
Section(header: Text("TOMORROW")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.blue).hideRowSeparator(insets: EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10))
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 10, bottom: 10, trailing: 10))
}
.listStyle(GroupedListStyle())
}
}
List 목록 배경 색상 설정
import SwiftUI
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color){
self.insets = insets
var alpha: CGFloat = 0
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "")
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(
minWidth: 0, maxWidth: .infinity, minHeight: Self.defaultListRowHeight, alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(background)
}
}
extension EdgeInsets{
static let defaultListRowInsets = Self(top: 10, leading: 10, bottom: 10, trailing: 10)
}
extension View {
func hideRowSeparator(insets: EdgeInsets = .defaultListRowInsets, background: Color = .white)
-> some View {
modifier(HideRowSeparatorModifier(insets: insets, background: background))
}
}
struct MyList: View{
List{
Section(header: Text("TODAY")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.green)
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 10, bottom: 10, trailing: 10))
Section(header: Text("TOMORROW")){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.blue)
.hideRowSeparator(insets: EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10),
background(Color.yellow))
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 10, bottom: 10, trailing: 10))
}
.listStyle(GroupedListStyle())
}
}
Section에 footer 추가, Text() 속성 부여
import SwiftUI
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color){
self.insets = insets
var alpha: CGFloat = 0
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "")
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(
minWidth: 0, maxWidth: .infinity, minHeight: Self.defaultListRowHeight, alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(background)
}
}
extension EdgeInsets{
static let defaultListRowInsets = Self(top: 10, leading: 10, bottom: 10, trailing: 10)
}
extension View {
func hideRowSeparator(insets: EdgeInsets = .defaultListRowInsets, background: Color = .white)
-> some View {
modifier(HideRowSeparatorModifier(insets: insets, background: background))
}
}
struct MyList: View{
var body: some View{
List{
Section(
header:
Text("TODAY")
.font(.headline)
.foregroundColor(.black)
,footer:
Text("HAVE A NICE DAY 👍")
){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.green)
.hideRowSeparator(insets: EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10))
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 10, bottom: 10, trailing: 10))
Section(
header:
Text("TOMORROW")
.font(.headline)
.foregroundColor(.black)
,footer:
Text("👍👍👍")
){
ForEach(1...20, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.blue)
.hideRowSeparator(insets: EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10),
background: Color.yellow)
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 10, bottom: 10, trailing: 10))
}
.listStyle(GroupedListStyle())
}
}
ContentView와 MyList 연동 (Navigation 적용하기)
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView{
ZStack(alignment: .bottomTrailing){
VStack(alignment: .leading, spacing: 0){
HStack{
NavigationLink(destination: MyList()){
Image(systemName: "line.horizontal.3")
.font(.largeTitle)
.foregroundColor(.black)
}
Spacer()
Image(systemName: "person.crop.circle.fill")
.font(.largeTitle)
}.padding(.top, 20)
.padding(.horizontal, 20)
Text("TODO LIST")
.font(.system(size: 40))
.fontWeight(.black)
.padding(.horizontal, 20)
.padding(.top,20)
ScrollView{
VStack{
MyCard()
MyProject(icon: "tray.fill", title: "책상 정리하기", start: "13:00", end: "14:00", bgColor: Color.blue)
MyProject(icon: "book.fill", title: "책 읽기", start: "14:00", end: "16:00", bgColor: Color.green)
MyProject(icon: "case.fill", title: "기숙사 짐 싸기", start: "16:00", end: "18:00", bgColor: Color.red)
MyBasic()
}.padding()
}
}
Circle()
.foregroundColor(Color.yellow)
.frame(width:60, height: 60)
.overlay(Image(systemName: "plus")
.font(.system(size:30))
.foregroundColor(.white))
.padding(10)
.shadow(radius: 20)
}//ZStack
}//NavigationView
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
- ContentView의 요소들을 NavigationView에 넣기
- 햄버거 바가 들어있는 HStack에 NavigationLink 적용
List 상단의 빈 공간은 navigationBarTitle 공간을 의미
List 상단의 navigationBarTitle 수정하기
import SwiftUI
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color){
self.insets = insets
var alpha: CGFloat = 0
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "")
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(
minWidth: 0, maxWidth: .infinity, minHeight: Self.defaultListRowHeight, alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(background)
}
}
extension EdgeInsets{
static let defaultListRowInsets = Self(top: 10, leading: 10, bottom: 10, trailing: 10)
}
extension View {
func hideRowSeparator(insets: EdgeInsets = .defaultListRowInsets, background: Color = .white)
-> some View {
modifier(HideRowSeparatorModifier(insets: insets, background: background))
}
}
struct MyList: View{
var body: some View{
List{
Section(
header:
Text("TODAY")
.font(.headline)
.foregroundColor(.black)
,footer:
Text("HAVE A NICE DAY 👍")
){
ForEach(1...3, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.green)
.hideRowSeparator(insets: EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10))
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 10, bottom: 10, trailing: 10))
Section(
header:
Text("TOMORROW")
.font(.headline)
.foregroundColor(.black)
,footer:
Text("👍👍👍")
){
ForEach(1...20, id: \.self){
itemIndex in MyProject(icon: "book.fill", title: "책 읽기 \(itemIndex)",
start: "13:00", end: "15:00", bgColor: Color.blue)
.hideRowSeparator(insets: EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10),
background: Color.yellow)
}
}
.listRowInsets(EdgeInsets.init(top: 10, leading: 10, bottom: 10, trailing: 10))
}
.listStyle(GroupedListStyle())
.navigationBarTitle("MY LIST")
}
}
메인 페이지(ContentView) 상단의 빈 공간은 NavigationView를 Stack에 쌓아서 생김
ContentView의 빈 공간 없애기
import SwiftUI
struct ContentView: View {
@State
var isNavigationBarHidden : Bool = false
var body: some View {
NavigationView{
ZStack(alignment: .bottomTrailing){
VStack(alignment: .leading, spacing: 0){
HStack{
NavigationLink(destination: MyList()){
Image(systemName: "line.horizontal.3")
.font(.largeTitle)
.foregroundColor(.black)
}
Spacer()
Image(systemName: "person.crop.circle.fill")
.font(.largeTitle)
}.padding(.top, 20)
.padding(.horizontal, 20)
Text("TODO LIST")
.font(.system(size: 40))
.fontWeight(.black)
.padding(.horizontal, 20)
.padding(.top,20)
ScrollView{
VStack{
MyCard()
MyProject(icon: "tray.fill", title: "책상 정리하기", start: "13:00", end: "14:00", bgColor: Color.blue)
MyProject(icon: "book.fill", title: "책 읽기", start: "14:00", end: "16:00", bgColor: Color.green)
MyProject(icon: "case.fill", title: "기숙사 짐 싸기", start: "16:00", end: "18:00", bgColor: Color.red)
MyBasic()
}.padding()
}
}
Circle()
.foregroundColor(Color.yellow)
.frame(width:60, height: 60)
.overlay(Image(systemName: "plus")
.font(.system(size:30))
.foregroundColor(.white))
.padding(10)
.shadow(radius: 20)
}//ZStack
.navigationTitle("Main")
.navigationBarHidden(self.isNavigationBarHidden)
.onAppear{
self.isNavigationBarHidden = true
}
}//NavigationView
}
}
@State는 값을 감지함
@State
var isNavigationBarHidden : Bool = false
isNavigationBarHidden을 default로 false 값 부여
NavigationView 안에
.navigationTitle("Main")
.navigationBarHidden(self.isNavigationBarHidden)
.onAppear{
self.isNavigationBarHidden = true
}
설정을 해주면 self.isNavigationBarHidden이 true가 되면서 뷰를 다시 그림
'강의 > etc' 카테고리의 다른 글
[SwiftUI fundamental Tutorial] GeometryReader (0) | 2021.08.31 |
---|---|
[SwiftUI fundamental Tutorial] Navigation View (0) | 2021.08.25 |
[SwiftUI fundamental Tutorial] Layout (0) | 2021.08.23 |
[SwiftUI fundamental Tutorial] Stack (0) | 2021.08.23 |
[SwiftUI fundamental Tutorial] Image (0) | 2021.08.22 |