이 페이지는 중국의 Jinxiansen의 SwiftUI 레포지토리를 참고해서 번역하였습니다.
이 글에 대한내용 은 기본적으로 스위프트 개발을 해보신 분들을 대상으로 잡고있습니다. 그래서 모든 디테일적인 부분을 다루진 않습니다. 혹시나 스위프트의 문법적인 부분이 필요하시다면 Swift 링크를 참고해주세요 :)
지나가시는 김에 레포지토리에 스타하나씩만 눌러주세요 ㅠㅠ
사실 필자도 스위프트에 대한 전문적 이해, SwiftUI에 대한 전문적 이해가 있는것이 아니라서, 틀린 부분이 있을수도 있습니다. 그런부분이 있다면 Facebook 또는 Mail 로 연락 주시거나 github issue 를 남겨주세요 :)
- macOS 15 Beta
- Xcode 11.0 Beta
- iOS 13.0 Beta
-
텍스트
-
이미지
-
-
기타(?)
-
스택
-
리스트
-
컨테이너 뷰
-
Architectural Views
-
알림(Alert)
-
바인딩
-
Data-Dependent Views
-
Environment Values
-
-
속성
-
Transactions
-
기본 제스쳐
-
복합 제스쳐
-
커스텀 제스쳐
Text
는 한줄이나, 그 이상의 텍스트를 UILabel
과 같은 형태로 나타 내어 줍니다.
만약 Text
를 생성 하고자 한다면, 그냥 Text("하고싶은말");
과 같은 형태로 진행하면 됩니다.
그리고, 폰트,색깔,그림자, 마진(??? : And I also, 마진조아)을 줄 수 있습니다.
예제:
Text("TEST TEXT")
.color(.red)
.bold()
.font(.system(.largeTitle))
.fontWeight(.medium)
.italic()
.shadow(color: .black, radius: 1, x: 0, y: 2)
TextField
는 일반적으로 사용하는 텍스트 상자 와 같아서, 텍스트 입력을 받을 수 있습니다.
예제:
TextField($data, placeholder:Text(placeholder), onEditingChanged: { changed in
print("onEditing: \(changed)")
}) {
print("data: \(self.data)")
}
.padding(10)
.frame(height: 50)
.textFieldStyle(.roundedBorder)
.padding(EdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 20))
}
}
만약 에러가 뜬다면,
self.data
쪽에서 에러가 뜨거나 placeholder 에서 에러가 뜬다면 name
이나 placeholde
State가 선언되지 않았을 가능성이 큽니다.
var body: some View {
위에
@State var data: String = ""
@State var placeholder: String = "let's input data"
와 같은 형태로 선언을 해주세요!
SecureField
는 일반적으로 패스워드 입력에 많이 사용된다. 사용방법은 TextField
와 동일하다.
예제:
SecureField($data, placeholder:Text(placeholder), onEditingChanged: { changed in
print("onEditing: \(changed)")
}) {
print("data: \(self.data)")
}
.padding(10)
.frame(height: 50)
.textFieldStyle(.roundedBorder)
.padding(EdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 20))
}
}
만약 에러가 뜬다면,
self.data
쪽에서 에러가 뜨거나 placeholder 에서 에러가 뜬다면 name
이나 placeholde
State가 선언되지 않았을 가능성이 큽니다.
var body: some View {
위에
@State var data: String = ""
@State var placeholder: String = "let's input data"
와 같은 형태로 선언을 해주세요!
Image
는 사진을 보여주기 위해 사용됩니다
예제:
Image("icon")
.resizable()
.frame(width: Length(100),
height: Length(100),
alignment: .center)
이미지는 Assets에 추가해주세요! 이미지 추가하는 법이 궁금하시다면... 요링크로
웹상의 이미지를 Image
를 통해 띄우려면, URLSession
을 사용해서, 직접 downloadWebImage
함수를 만들어서 사용 할 수 있습니다.
Example:
var body: some View {
Image(uiImage: self.uiImage ?? placeholderImage)
.resizable()
.onAppear(perform: downloadWebImage)
.frame(width: Length(80),
height: Length(80),
alignment: .center)
.tapAction {
print("Tap ")
}
}
func downloadWebImage() {
guard let url = URL(string: "https://developer.apple.com/assets/elements/icons/swiftui/swiftui-96x96_2x.png") else {
print("Invaild URL")
return
}
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let data = data, let image = UIImage(data: data) {
self.uiImage=image
}else {
print("error: \(String(describing: error)))
}}
}
만약 에러가 난다면, var body: some View {
위에
@State private var uiImage: UIImage? = nil
let placeholderImage = UIImage(named: "icon")!
를 입력해주세요!
Button
은, 클릭 이벤트를 발생시키기 위해 사용됩니다.
예제
Button(action: {
print("Tap")
}) {
Text("I'm a Button")
}
NavigationButtonPage
는 눌러사 다음 네비게이션 페이지로 가기 위해 사용됩니다.
예제
NavigationButton(destination: NavigationButtonPage()) {
Text("NavigationButton").bold().color(.orange).font(.largeTitle)
}.navigationBarItem(title: Text("Page"))
만약 NavigationButtonPage 선언과 관련해서 오류
가 뜬다면,
새로운 swiftui 파일을 하나 만들고, 페이지 이름을 NavigationButtonPage
으로 만들어주세요!
PresentationButton
은 페이지를 팝업으로 띄우기 위해서 사용됩니다.
예제
PresentationButton(PageRow(title: "PresentationButton", subTitle: "pop up a page"),
destination: Text("I'm Text")) {
print("Present 🦄")
}
Picker
can customize the selector of the data source.
Picker
는 데이터 선택기 입니다. (여러 데이터중 스크롤로 하나를 선택할때 사용합니다. 예시로,회원가입할때 성별 체크와 같은곳에 주로 사용합니다.)
예제
Picker(selection: $selectedStrength, label: Text("Strength")) {
ForEach(0 ..< strengths.count) {
Text(self.strengths[$0]).tag($0)
}
}
.pickerStyle(.wheel)
}
만약 selectedStrength 선언과 관련해서 오류
가 뜬다면
var body: some View {
위에
var strengths = ["Mild", "Medium", "Mature"]
@State var selectedStrength = 0
를 선언해주세요!
DatePicker
는 위에서 이야기한 picker 의 날짜 버전입니다 :D
예제:
DatePicker(
VStack(alignment: .center, spacing: 10) {
Text("DatePicker").bold()
DatePicker(
$server.date,
minimumDate: Calendar.current.date(byAdding: .year,
value: -1,
to: server.date),
maximumDate: Calendar.current.date(byAdding: .year,
value: 1,
to: server.date),
displayedComponents: .date
)
}
.padding(.top)
.navigationBarTitle(Text("DatePicker"))
}
}
)
만약 에러가 난다면, var body: some View {
위에
@ObjectBinding var server = DateServer()
를 선언하고,
var body: some View {
의 괄호가 끝나는 부분에,
class DateServer: BindableObject {
var didChange = PassthroughSubject<DateServer,Never>()
var date: Date = Date() {
didSet {
didChange.send(self)
print("Date Changed: \(date)")
}
}
}
\
로 클래스를 선언을 해주세요!
Toggle
은 선택된 상태를 변경하기 위해 사용됩니다
예제:
Toggle(isOn: $isOn) {
Text("State: \(self.isOn == true ? "Open":"open")")
}.padding(20)
만약 isOn 관련 에러가 뜬다면, var body: some View {
위에
@State var isOn = false
를 선언해주세요!
Slider
은 선택된 값을 제한된 범위에서 선택할 수 있게 해줍니다.
예제:
Slider(value: $var)
Stepper
는 값을 올리고,내리기 위해 사용됩니다.
예제:
Stepper(value: $value, step: 2, onEditingChanged: { c in
print(c)
}) {
Text("Stepper Value: \(self.value)")
}.padding(50)
만약 에러가 난다면
SegmentedControl
은 세그먼테이션 상태 선택을 위해서 사용됩니다.
예제:
SegmentedControl(selection: $currentIndex) {
ForEach(0..<items.count) { index in
Text(self.items[index]).tag(index)
}
}.tapAction {
print("currentIndex: \(self.currentIndex)")
}
WebView
is used to display an open web page, 예제:
struct WebViewPage : UIViewRepresentable {
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
let req = URLRequest(url: URL(string: "https://www.apple.com")!)
uiView.load(req)
}
}
UIViewController
is used to display the UIViewController that opens UIKit in SwiftUI and opens the SwiftUI
View in UIViewController.
예제:
First define:
struct ControllerPage<T: UIViewController> : UIViewControllerRepresentable {
typealias UIViewControllerType = UIViewController
func makeUIViewController(context: UIViewControllerRepresentableContext<ControllerPage>) -> UIViewController {
return T()
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<ControllerPage>) {
debugPrint("\(#function):\(type(of: T.self))")
}
}
Then use this:
NavigationButton(destination: ControllerPage<UIKitController>()) {
PageRow(title: "UIViewController",subTitle: "Open UIViewController")
}
HStack
is used to arrange the subviews on a horizontal line.
예제:
HStack {
Text("made in China.")
Divider() // Just add a line.
Text("the People's Republic Of China.")
}
VStack
is used to arrange the subviews on a vertical line.
예제:
VStack {
Text("made in China.")
Divider() // Just add a line.
Text("the People's Republic Of China.")
}
ZStack
is used to override the subview, aligned on two axes.
예제:
ZStack {
Text("made in China.")
Divider() // Just add a line.
Text("the People's Republic Of China.")
}
List
list container to display a list of data.
Examples:
List(0..<5) { item in
Text("Hello World !")
}.navigationBarTitle(Text("List"), displayMode: .large)
ScrollView
is a scroll view container.
예제:
ScrollView {
Text("SwiftUI").padding(20)
Divider()
Image("icon").resizable()
.frame(width: 300, height: 300, alignment: .center)
Divider()
Text("Views and ... user interface.")
}
.border(style, width: 1,cornerRadius: 10)
.padding(10)
.navigationBarTitle(Text("ScrollView"))
ForEach
is used to present a view based on a collection of existing data.
예제:
let data = (0..<5).map { $0 }
var body: some View {
ForEach(data) { e in
Text("Hello \(e)")
.bold()
.font(.system(size: 25, design: .monospaced))
.padding(5)
}
Group
is used to aggregate multiple views, and the properties set on the Group will be applied to each child view.
예제:
Group {
Text("Hello World !")
Text("Hello World !")
}
Waiting for release.
Section
is used to create the header/footer view content, which is generally used in conjunction with the List
component.
예제:
Section(header: Text("I'm header"), footer: Text("I'm footer")) {
ForEach(0..<3) {
Text("Hello \($0)")
}
}
NavigationView
is used to create a view container that contains the top navigation bar.
예제:
NavigationView {
Text("🧚♂️🧚♀️🧜♂️🧜♀️🧞♂️🧞♀️").blur(radius: 5)
Text("Swifter Swifter").bold().color(.orange).font(.largeTitle)
}.navigationBarTitle(Text("NavigationView"))
TabBar
is used to create a view container that contains the bottom TabBar.
예제:
TabbedView(selection: $index) {
ForEach(0 ..< imgs.count) { item in
TabItemPage(index: item)
.tabItemLabel(Image(self.imgs[item]))
.tag(item)
}
}
Waiting for release.
Waiting for release.
Alert
is used to display a bullet reminder that needs to be associated with a trigger event.
예제:
presentation($showsAlert, alert: {
Alert(title: Text("Hello"))
})
ActionSheet
is used to pop up a selection box.
예제:
ActionSheet(title: Text("Title"),
message: Text("Message"),
buttons:
[.default(Text("Default"), onTrigger: {
print("Default")
self.showSheet = false
}),.destructive(Text("destructive"), onTrigger: {
print("destructive")
self.showSheet = false
}),.cancel({
print("Cancel")
self.showSheet = false
})])
Modal
is used to pop up a view.
예제:
Modal(Text("Modal View"),onDismiss: {
print("View Dismiss !")
})
Popover
is used to pop up a view, see the results below.
예제:
Popover(content: Text("Popover View")) {
print("Popover Dismiss !")
}
- 여기 있는 모든 샘플코드는 Example project 안에 포함되어 있습니다.
- 만약, 여기 적힌 샘플 코드보다 깔끔하고 이쁘게 만들어 주실수 있으시다면 꼭 이슈를 넣어주세요!! (
필자는 스위프트 알못입니다) - 만약 여기 예제코드에 에러가 있거나, 궁금한게 있으시다면 Issue 를 남겨주세요!!
Mail : [email protected]
Facebook : 한우영
Github : cokia
SwiftUI CheatSheet 프로젝트는 GPL-3.0 license 입니다 :)